1. 程式人生 > >ES5_call,apply,bind用法詳解

ES5_call,apply,bind用法詳解

call()/apply()是立即呼叫函式,都是在特定的作用域中呼叫函式,等於設定函式體內this物件的值,以擴充函式賴以執行的作用域。

一般來說,this總是指向呼叫某個方法的物件,但是使用call()和apply()方法時,就會改變this的指向。

不同點:接收引數的方式不同

  • apply()方法 接收兩個引數,一個是函式執行的作用域(this),另一個是引數陣列。

語法:apply([thisObj [,argArray] ]);,呼叫一個物件的一個方法,另一個物件替換當前物件。

說明:如果argArray不是一個有效陣列或不是arguments物件,那麼將導致一個  TypeError,如果沒有提供argArray和thisObj任何一個引數,那麼Global物件將用作thisObj。

  • call()方法 第一個引數和apply()方法的一樣,但是傳遞給函式的引數必須列舉出來。

語法:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);,應用某一物件的一個方法,用另一個物件替換當前物件。

說明: call方法可以用來代替另一個物件呼叫一個方法,call方法可以將一個函式的物件上下文從初始的上下文改變為thisObj指定的新物件,如果沒有提供thisObj引數,那麼Global物件被用於thisObj。

當沒有使用call方法時:

<script>
    var obj={username:'xue'};
    function foo() {
        console.log(this);
    }
    foo();
</script>

this就是指向window。

當使用call方法時:

foo.call(obj);

this就指向了我給它的物件

當使用apply時:

foo.call(obj);
foo.apply(obj);

結果一模一樣。

區別:傳參

<script>
    var obj={username:'xue'};
    function foo(data) {
        console.log(this,data);
    }
    foo.call(obj,33); //直接從第二個引數開始,依次傳入
    foo.apply(obj,[33]);  //第二個引數必須是陣列,引數放在數組裡
</script>

如果apply相call那樣傳參的話,就會報錯,以上才是正確模式,控制檯輸出一模一樣。

bind

var obj={username:'xue'};
    function foo(data) {
        console.log(this,data);
    }
    
    foo.bind(obj);

這樣寫,控制檯什麼都不輸出,bind的特點:繫結完this不會立即呼叫當前的函式,而是將函式返回

 var bar=foo.bind(obj);
    console.log(bar);

返回的是一個函式,如果讓函式立即執行就這樣寫:

foo.bind(obj)();

bind傳參:

bind傳參的方式同call一樣

foo.bind(obj,33)();

call、apply、bind三者的區別

call和apply指定了this,它會立即呼叫當前的函式,而bind不會立即呼叫函式,是把函式返回,bind通常用它來指定回撥函式的this:

比如:

 setTimeout(function () {
        console.log(this);
    }.bind(obj),1000);

如果不使用bind那麼this指向的就是window,使用了bind,this就會指向這個obj。