JS 中call()和apply()以及bind()的區別

一、方法定義:

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

上面的定義看一遍是很懵的,不過自己遍寫例子遍反覆讀的時候,會有種撥開雲霧的感覺。

call 與 apply 的相同點:

  • 方法的含義是一樣的,即方法功能是一樣的;
  • 第一個參數的作用是一樣的;

call 與 apply 的不同點: 兩者傳入的列表形式不一樣

  • call可以傳入多個參數;
  • apply只能傳入兩個參數,所以其第二個參數往往是作爲數組形式傳入

存在的意義:實現(多重)繼承

二、舉個栗子

        var name = '小張', age = 17;
        var obj = {
            name: '小劉',
            objAge: this.age,  //this指向window
            myFun: function(){
                return this.name + this.age;  //this指向obj
            }
        }
        
        console.log( obj.objAge );    //17
        console.log( obj.myFun() );   //小劉 undefined

比較一下這兩者this的差別,第一個打印裏面的this指向obj,第二個全局聲明的shows()函數this是window。

  1. call()、 apply()、 bind() 都是用來重定義this這個對象的!
        var name = '小張', age = 17;
        var obj = {
            name: '小劉',
            objAge: this.age,
            myFun: function(){
                return this.name + this.age; 
        }
        var db = {
            name: '小黃',
            age: 18
        };
        
        console.log( obj.myFun.call() );      //小張17  this指向window
        console.log( obj.myFun.call(db) );    //小黃18  this指向對象db
        console.log( obj.myFun.apply() );     //小張17
        console.log( obj.myFun.apply(db) );   //小黃18
        console.log( obj.myFun.bind()() );    //小張17  bind返回的是函數,必須調用才能執行
        console.log( obj.myFun.bind(db)() );  //小黃18
  1. 對比call、 bind、 apply 傳參情況下
        var name = '小張', age = 17
        var obj = {
            name: '小劉',
            objAge: this.age,  
            myFun: function( fm, t ){
                return this.name + this.age + '來自' + fm + '去往' + t;  
            }
        }
        var db = {
            name: '小黃',
            age: 18
        };

        console.log( obj.myFun.call(db, '江西', '深圳') );     //小黃18來自江西去往深圳
        console.log( obj.myFun.apply(db, ['江西', '深圳']) );  //小黃18來自江西去往深圳
        console.log( obj.myFun.bind(db, '江西', '深圳')() );   //小黃18來自江西去往深圳 

從上面的結果來看:

call、 bind、 apply 這三個函數的第一個參數都是this的指向對象

第二個參數差別就來了:

call 的參數是直接放進去的,第二第三第n個參數全都用逗號分隔,直接放到後面obj.myFun.call(db,‘江西’, …, ‘string’)。

apply的所有參數都必須放在一個數組裏面傳進去。

bind除了返回函數以外,它的參數和call 一樣。

當然,三者的參數不限定是String 類型,允許是各種類型,包括函數,對象等等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章