在JavaScript中,call、apply和bind是Function對象自帶的三個方法,都是為了改變函數(shù)體內(nèi)部this的指向。
? ? ? ? ? ?apply 、 call 、bind三者第一個參數(shù)都是this要指向的對象,也就是想指定的上下文;apply 、 call 、bind三者都可以利用后續(xù)參數(shù)傳參;bind 是返回對應函數(shù),便于稍后調(diào)用;apply 、call則是立即調(diào)用。
下面是例子:
但是如果我們有一個對象banana= {color : 'yellow'},我們不想重新定義 say 方法,那么我們可以通過 call 或 apply 用 apple 的 say 方法:
apple.say.call(banana); //此時的this的指向已經(jīng)同過call()方法改變了,指向的是banana,this.color就是banana.color='yellow';//結(jié)果是My color is yellow? apple.say.apply(banana);//同理,此時的this的指向已經(jīng)同過apply()方法改變了,指向的是banana,this.color就是banana.color;
// 如果傳入的是 null: apple.say.apply(null); // null是window下的,此時,this 就指向了window ,但是window下并沒有clolr這個屬性,因此this.clolr就是window.color=undefined;
2.對于 apply、call 二者而言,作用完全一樣,只是接受?參數(shù)?的方式不太一樣。call 是把參數(shù)按順序傳遞進去,而 apply 則是把參數(shù)放在數(shù)組?里。
var array1 = [12,'foo',{name:'Joe'},-2458];
var array2 = ['Doe' , 555 , 100];
Array.prototype.push.call(array1, array2);
// 這里用 call 第二個參數(shù)不會把 array2 當成一個數(shù)組,而是一個元素
//等價于array1.push(‘‘'Doe' , 555 , 100’’),array1.length=5;
Array.prototype.push.apply(array1, array2);?
// 這里用 apply 第二個參數(shù)是一個數(shù)組
// 等價于:? array1.push('Doe' , 555 , 100),array1.length=7;
3.類數(shù)組使用數(shù)組方法
vardivElements = document.getElementsByTagName('div');
//雖然 divElements 有l(wèi)ength屬性,但是他是一個偽數(shù)組,不能使用數(shù)組里面的方法
Array.prototype.slice.call(document.getElementsByTagName('div'));
或者是用Array.from()轉(zhuǎn)化一下;
4.驗證一個對象/數(shù)組的類型可以用:
Object.prototype.toString.call(obj) ;
5.bind()方法,MDN 的解釋是:bind()方法會創(chuàng)建一個?新函數(shù),稱為綁定函數(shù),當調(diào)用這個綁定函數(shù)時,
綁定函數(shù)會以創(chuàng)建它時傳入bind()方法的第一個參數(shù)?作為this,傳入bind()方法的?第二個以及以后的參
數(shù)加上綁定函數(shù)運行時本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)用原函數(shù)。
var bar =function(){
? ? console.log(this.x);
}
var foo = {x:3};
bar(); // undefined?
var func =bar.bind(foo);//此時this已經(jīng)指向了foo,但是用bind()方法并不會立即執(zhí)行,而是創(chuàng)建一個新函數(shù),如果要直接調(diào)用的話 可以 bar.bind(foo)()
func(); // 3
多次bind()是無效的,只有第一次生效;
6.apply、call、bind三者相比較,之間又有什么異同呢?何時使用apply、call,何時使用bind呢。簡單的一個例子:
var obj = {
? x: 81,
};
? var foo = {
? getX: function() {
? ? return this.x;
? }
}
console.log(foo.getX.bind(obj)());? //81返回一個function,需要再次調(diào)用;
console.log(foo.getX.call(obj));//81
console.log(foo.getX.apply(obj));//81