問答
1. apply枣耀、call 有什么作用芬位,什么區(qū)別
Javascript的每個(gè)Function對(duì)象中有一個(gè)apply方法:
function.apply([thisObj[,argArray]])
還有一個(gè)類似功能的call方法:
function.call([thisObj[,arg1[, arg2[, [,.argN]]]]])
它們各自的定義:
apply:應(yīng)用某一對(duì)象的一個(gè)方法武氓,用另一個(gè)對(duì)象替換當(dāng)前對(duì)象东帅。
call:調(diào)用一個(gè)對(duì)象的一個(gè)方法岭埠,以另一個(gè)對(duì)象替換當(dāng)前對(duì)象脆丁。它們的共同之處:
都“可以用來代替另一個(gè)對(duì)象調(diào)用一個(gè)方法,將一個(gè)函數(shù)的對(duì)象上下文從初始的上下文改變?yōu)橛?thisObj 指定的新對(duì)象稚叹。它們的不同之處:
apply:
最多只能有兩個(gè)參數(shù)——新this對(duì)象和一個(gè)數(shù)組 argArray端礼。如果給該方法傳遞多個(gè)參數(shù)禽笑,則把參數(shù)都寫進(jìn)這個(gè)數(shù)組里面,當(dāng)然蛤奥,即使只有一個(gè)參數(shù),也要寫進(jìn)數(shù)組里面僚稿。如果 argArray 不是一個(gè)有效的數(shù)組或者不是 arguments 對(duì)象凡桥,那么將導(dǎo)致一個(gè) TypeError。如果沒有提供 argArray 和 thisObj 任何一個(gè)參數(shù)蚀同,那么 Global 對(duì)象將被用作 thisObj缅刽,并且無法被傳遞任何參數(shù)。
call:
則是直接的參數(shù)列表蠢络,主要用在js對(duì)象各方法互相調(diào)用的時(shí)候衰猛,使當(dāng)前this實(shí)例指針保持一致,或在特殊情況下需要改變this指針。如果沒有提供 thisObj 參數(shù)刹孔,那么 Global 對(duì)象被用作 thisObj啡省。
更簡單地說,apply和call功能一樣髓霞,只是傳入的參數(shù)列表形式不同:如 func.call(func1,var1,var2,var3) 對(duì)應(yīng)的apply寫法為:func.apply(func1,[var1,var2,var3])
也就是說:call調(diào)用的為單個(gè)卦睹,apply調(diào)用的參數(shù)為數(shù)組
function sum(a,b){
console.log(this === window);//true
console.log(a + b);
}
sum(1,2);
sum.call(null,1,2);
sum.apply(null,[1,2]);
作用
- 調(diào)用函數(shù)
var info = 'tom';
function foo(){
//this指向window
var info = 'jerry';
console.log(this.info); //tom
console.log(this===window) //true
}
foo();
foo.call();
foo.apply();
- call和apply可以改變函數(shù)中this的指向
var obj = {
info:'spike'
}
foo.call(obj); //這里foo函數(shù)里面的this就指向了obj
foo.apply(obj);
- 借用別的對(duì)象的方法
eg:求數(shù)組中的最大值
var arr = [123,34,5,23,3434,23];
//方法一
var arr1 = arr.sort(function(a,b){
return b-a;
});
console.log(arr1[0]);
//方法二
var max = Math.max.apply(null,arr) //借用別的對(duì)象的方法
console.log(max);
代碼
1. 以下代碼輸出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi() // John: hi!,this指向調(diào)用sayHi()的john對(duì)象
2. 下面代碼輸出什么方库,為什么
func()
function func() {
alert(this) //window结序,因?yàn)樵诤瘮?shù)被直接調(diào)用時(shí)this綁定到全局對(duì)象。在瀏覽器中纵潦,window 就是該全局對(duì)象
}
3. 下面代碼輸出什么
function fn0(){
function fn(){
console.log(this);
}
fn();
}
fn0(); //window. 函數(shù)嵌套產(chǎn)生的內(nèi)部函數(shù)的this不是其父函數(shù)徐鹤,仍然是全局變量
document.addEventListener('click', function(e){
console.log(this); //#document.
//在事件處理程序中this代表事件源DOM對(duì)象
setTimeout(function(){
console.log(this); //window.
//setTimeout、setInterval這兩個(gè)方法執(zhí)行的函數(shù)this也是全局對(duì)象
}, 200);
}, false);
4. 下面代碼輸出什么邀层,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john) //John
//call(john)傳入了john這個(gè)執(zhí)行上下文返敬,this指向john這個(gè)對(duì)象
5. 代碼輸出?
var john = {
firstName: "John",
surname: "Smith"
}
function func(a, b) {
alert( this[a] + ' ' + this[b] )
}
func.call(john, 'firstName', 'surname') //John Smith
//this指向john這個(gè)對(duì)象
6. 以下代碼有什么問題被济,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指$btn
this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
//修改后:
var module= {
bind: function(){
var cur = this; //將this代表的module存到cur
$btn.on('click', function(){
console.log(this) //$btn
cur.showMsg(); //饑人谷
})
},
showMsg: function(){
console.log('饑人谷');
}
}
7. 下面代碼輸出什么
var length = 3;
function fa() {
console.log(this.length);
}
var obj = {
length: 2,
doSome: function (fn) {
console.log(this)// obj
fn(); //3. 函數(shù)嵌套的內(nèi)部函數(shù)this指向全局變量
arguments[0](); //1. arguments對(duì)象在調(diào)用fa救赐,所以this指arguments對(duì)象。長度為1
}
}
obj.doSome(fa)
8. 下面代碼輸出什么? why
obj = {
go: function() { alert(this) }
}
obj.go(); //obj. go是obj身上的一個(gè)方法只磷,就算放在全局環(huán)境下经磅,this依舊指向obj;
(obj.go)(); //obj. 這是一個(gè)自執(zhí)行函數(shù)钮追, 依舊是obj去調(diào)用了這個(gè)方法预厌;
(a = obj.go)(); //window
//將函數(shù)賦值給一個(gè)全局變量a;這個(gè)時(shí)候a()執(zhí)行的話元媚,就變成了依賴的是全局環(huán)境轧叽,所以this指向了window苗沧;
(0 || obj.go)(); //window
//相當(dāng)于 (temp = 0 || obj.go)(),即相當(dāng)于上一條例子