在 JavaScript 中
-
call
、apply
和 bind
是 Function 對象自帶的三個方法,都是為了改變函數體內部 this
的指向。
-
call
、apply
和 bind
三者第一個參數都是 this
要指向的對象,也就是想指定的上下文。
-
call
、apply
和 bind
三者都可以利用后續參數傳參。
-
bind
是返回對應 函數,便于稍后調用;apply
、call
則是立即調用 。
舉個栗子
function fruits() {}
fruits.prototype = {
color: 'red',
say: function() { console.log('My color is ' + this.color);
}
} var apple = new fruits;
apple.say();
如果我們有一個對象 banana= {color : 'yellow'}
,我們不想重新定義 say 方法,那么我們可以通過 call
或 apply
用 apple 的 say 方法:
var banana = { color: 'yellow' };
apple.say.call(banana); // 此時的this的指向已經同過call()方法改變了,指向的是banana,this.color就是banana.color='yellow'; // 結果是My color is yellow
apple.say.apply(banana); // 同理,此時的this的指向已經同過apply()方法改變了,指向的是banana,this.color就是banana.color ='yellow'; // 結果是My color is yellow
apple.say.apply(null); // null是window下的,此時,this 就指向了window ,但是window下并沒有clolr這個屬性,因此this.clolr就是window.color=undefined; // 結果是My color is undefined
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
call
和 apply
的區別
二者的作用完全一樣,知識接受 參數 的方式不太一樣。
call
是把參數按順序傳遞進去,而 apply
則是把參數放在 數組 里面。
var array1 = [12,'foo',{name:'Joe'},-2458]; var array2 = ['Doe' , 555 , 100]; Array.prototype.push.call(array1, array2); Array.prototype.push.apply(array1, array2);
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
類(偽)數組使用數組方法
var divElements = document.getElementsByTagName('div'); Array.isArray(divElements); var domNodes = Array.prototype.slice.call(document.getElementsByTagName('div')); Array.isArray(domNodes);
驗證一個對象的類型可以用
Object.prototype.toString.call(obj)
bind()
方法
bind()
方法會創建一個 新函數,稱為綁定函數,當調用這個綁定函數時,綁定函數會以創建它時傳入 bind()
方法的第一個參數 作為 this,傳入 bind()
方法的 第二個以及以后的參數加上綁定函數運行時本身的參數按照順序作為原函數的參數來調用原函數。
注意
:bind()
方法創建的函數不會立即調用,在下面的例子中,最后 func()
才調用了函數,這是它與 call
和apply
的區別。
var bar = function(){ console.log(this.x);
} var foo = {
x:3 }
bar(); var func = bar.bind(foo); func();
在 Javascript 中,多次 bind()
是無效的。更深層次的原因, bind()
的實現,相當于使用函數在內部包了一個 call / apply
,第二次 bind()
相當于再包住第一次 bind()
,故第二次以后的 bind
是無法生效的。
var bar = function(){ console.log(this.x);
} var foo = {
x:3 } var sed = {
x:4 } var func = bar.bind(foo).bind(sed);
func(); var fiv = {
x:5 } var func = bar.bind(foo).bind(sed).bind(fiv);
func();