call,apply,bind 爲何要叫作三兄弟,是由於他們有一個共同的父親——Function.prototype,因此他們都是實例方法,不妨我們現場"滴血認親"一下javascript
Function.prototype.hasOwnProperty('call');
Function.prototype.hasOwnProperty('apply');
Function.prototype.hasOwnProperty('bind');
複製代碼
上面三條語句的返回結果都爲true,算了有圖有真相,上圖java
所以,這三兄弟能夠在對象,數組,函數中均可以使用。數組
call方法,能夠指定所用目標函數的this指向,即函數執行時所在的做用域(上下文),而且在指定的做用域調用這個函數,當即執行。app
var content = {
number: 2
};
var number = 1;
function func(){
console.log(this.number);
}
a(); //結果爲1
a.call(); //沒有傳遞參數仍是默認所在的做用域
a.call(content); //指向content的內部做用域,此時結果爲2
複製代碼
即,當咱們執行a函數時,它指向的是全局對象,因此this指向的也就是全局對象;但當咱們幫它指向content對象時,這個函數的執行做用域也就變爲了content對象的做用域函數
call方法能夠傳遞多個參數,第一個參數即爲指定的this的指向,即要提供這個函數要執行所存在的做用域的傢伙,後面的參數是函數調用時須要使用的參數,直接用","號分割便可。ui
若是 call的第一個參數爲null或者undefined或者this,它等同於指向全局對象。this
apply方法身爲二哥,天然是和大哥的做用很是類似,他們都是改變this指向來在制定的做用域中調用這個函數,當即執行,惟一的不一樣可能就是二哥Apply相比較於大哥Call來講它更"挑食"。它只能接收兩個參數,第一個參數爲this指向的對象,第二個參數爲執行時須要的參數,注意,它只要數組做爲他的第二個參數。spa
咱們讓大哥和二哥實現相同的功能來看一下他們的不一樣prototype
function sum(a,b){
return a + b;
}
sum.call(this,1,2); //結果爲3
sum.apply(this,[1,2]); //結果爲3
複製代碼
因此,當咱們要讓某個數組來執行某種方法時,使用apply方法相較於call方法能方便不少。好比咱們想快速的查找一個數組中的最大值code
var a = [1,2,3,4,5,7,8,9,45,123,111];
Math.max.apply(this,a); // 123
複製代碼
bind方法用於指定函數內部的this指向,而後返回一個新函數,但它不會當即執行,它只是給這個函數增長了修飾,並無調用它。
var content = {
number: 2
};
function func(){
console.log(this.number);
}
//call方法
func.call(content); // 2
//apply方法
func.apply(content); //2
//bind方法
func.bind(content)(); //2
複製代碼
bind的參數要求和大哥同樣,即爲一個一個的傳參.
call 和 apply 方法在調用後會當即執行,而bind則是把做用域修改後的函數返回,須要本身再次手動調用。
從上面的例子咱們能夠看到三兄弟十分類似,但也各有千秋。
同:
異: