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。