call() 、apply()、bind()這三個方法的作用都是:改變函數執行的上下文,換句話說就是改變函數體內部的this的指向,以此來擴充函數賴以運行作用域。
舉個栗子
沒有call()函數時 函數foo中的this指向的是window對象,foo.call(obj)之後 this指向的是obj這個對象.
區別:
1、bind與call、apply的區別
bind()是返回的是執行上下文被改變的函數且不會立即執行,call()、apply()直接執行該函數;
2、apply與call的區別:兩者的參數
兩者的第一個參數都相同—指定的對象,這個對象就是該函數的執行上下文。
apply :最多只能有兩個參數,第二個參數爲數組或者arguments對象。如果傳遞多個參數,則把參數都寫進數組裏面,當然,即使只有一個參數,也要寫進數組裏。
語法:apply(thisObj,[argArray])
function sum(num1,num2){
return num1+num2;
}
function applySum1(num1,num2){
return sum.apply(this,arguments);
}
function applySum2(num1,num2){
return sum.apply(this,[num1,num2]);
}
console.log(applySum1(8,9));//17
console.log(applySum2(7,8));//15
call: 其他的參數必須直接傳給函數,要一個一個的列出來
語法:call(thisObj,param1,param2…)
function sum(num1,num2){
return num1+num2;
}
function callSum(num1,num2){
return sum.call(this,[num1,num2]);
}
console.log(callSum(8,9));//17
下面寫個栗子對比一下三者的用法
var test = {
a : 5,
b : 6,
sum : function (a,b) {
var self = this;
function getA() {
console.log(self.a);//2
return self.a;
}
function getB(){
console.log(self.b);//3
return self.b;
}
alert(a);
alert(b);
return getA() + getB();
}
}
var obj = {a:2,b:3};
alert(test.sum.call(obj,4,5)); // 調用時self = this = obj,alert順序4,5,5
alert(test.sum.apply(obj,[6,7])); // 調用時self = this = obj,alert順序6,7,5
var sum = test.sum.bind(obj,8); // 此處返回一個只有一個參數的函數sum(b)
console.log(sum);
alert(sum(9)); //alert 5
console.log(sum);的結果如下:
從這個實例中可以看出:
bind()方法所返回的函數的length(形參數量)等於原函數的形參數量減去傳入bind()方法中的實參數量(第一個參數以後的所有參數),因爲傳入bind中的實參都會綁定到原函數的形參。