call,apply和bind的區別

oliverhuang發表於2019-02-10

都是修改function內上下文this的指向

  • 如果第一個引數傳入的是null的話,那麼瀏覽器中預設是window,node中預設是global,但是函式體內部如果是嚴格模式,那麼this仍然是null
  • 可以針對類陣列物件(可以通過索引訪問元素,並且擁有 length 屬性;沒有陣列的其他方法,例如 push , forEach , indexOf 等。)完成陣列的操作,比如Array.prototype.pushArray.prototype.slice等等
  • 還可以借用其他物件的方法,實現類似繼承的效果。
var A = function( name ){ 
    this.name = name;
};
var B = function(){ 
    A.apply(this,arguments);
};
B.prototype.getName = function(){ 
    return this.name;
};
var b=new B('sven');
console.log( b.getName() ); // 輸出:  'sven'
複製程式碼

call

fn.call(this,arg1,arg2...)

call的第一個變數是要指向的this的新object

接受的引數列表

apply

fn.apply(this,[arg1,arg2...])

apply的第一個變數是要指向的this的新object

接受的是引數陣列(或者類陣列物件)

bind

bind其實可以通過call和apply進行實現

Function.prototype.bind = function( context ){ 
    var self = this; // 儲存原函式
    return function(){ // 返回一個新的函式
        return self.apply( context, arguments );//執行新的函式的時候,會把之前傳入的context當作新的函式體的this
    } 
};
複製程式碼
Function.prototype.bind = function(){ 
    var self = this, // 儲存原函式
        context = [].shift.call( arguments ),//需要繫結的this上下文
        args = [].slice.call( arguments ); //剩餘的引數轉成陣列
    return function(){ // 返回一個新的函式
        return self.apply( context, [].concat.call( args, [].slice.call( arguments ) ) ); 
        //執行新的函式的時候,會把之前傳入的context當作新的函式體的this
        //並且組合兩次分別傳入的引數,作為新的函式的引數
    } 
};
複製程式碼

fn.bind(this,arg1,arg2...)

bind的第一個變數是要指向的this的新object

函式需要的引數是從第二個開始按照數量傳入的

區別是返回一個this已經繫結到新的object的函式

參考連結

developer.mozilla.org/zh-CN/docs/…

developer.mozilla.org/zh-CN/docs/…

developer.mozilla.org/zh-CN/docs/…

相關文章