天天看點

CALL()、APPLY()、BIND的用法和差別

call、apply、bind的作用是改變函數運作時this的指向。

apply:調用一個對象的一個方法,用另一個對象替換目前對象。例如:B.apply(A, arguments);即A對象應用B對象的方法。

call:調用一個對象的一個方法,用另一個對象替換目前對象。例如:B.call(A, args1,args2);即A對象調用B對象的方法。

function add(c, d){ 
    return this.a + this.b + c + d; 
} 
var o = {a:1, b:3}; 
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16 
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34 
           

當一個函數被儲存為對象的一個方法時,如果調用表達式包含一個提取屬性的動作,那麼它就是被當做一個方法來調用,此時的this被綁定到這個對象。

var a = 1
    var obj1 = {
      a:2,
      fn:function(){
        console.log(this.a)
      }
    }
    obj1.fn()//2    
           

此時的this是指obj1這個對象,obj1.fn()實際上是obj1.fn.call(obj1),事實上誰調用這個函數,this就是誰。補充一下,DOM對象綁定事件也屬于方法調用模式,是以它綁定的this就是事件源DOM對象。如:

document.addEventListener('click', function(e){
    console.log(this);
    setTimeout(function(){
        console.log(this);
    }, 200);
}, false);
點選頁面,依次輸出:document和window對象
           

解析:點選頁面監聽click事件屬于方法調用,this指向事件源DOM對象,即obj.fn.apply(obj),setTimeout内的函數屬于回調函數,可以這麼了解,f1.call(null,f2),是以this指向window。

bind() 方法和前兩者不同在于: bind() 方法會傳回執行上下文被改變的函數而不會立即執行,而前兩者是直接執行該函數。他的參數和call()相同。