call() , apply() 與 bind() 實例詳解

call() , apply() 與 bind() 詳解

咱們知道能夠用call(), apply()bind()這三個函數都是用來完成函數調用,而且設置this指向。 call()apply()是 ECMAScript3 標準引入,而bind()函數則是在 ECMAScript 5 引入。 這邊文章會用幾個小例子來回憶一下他們之間有什麼不同。數組

用法

call()apply() 會當即調用函數, 而bind()只會返回一個函數引用,當後面真正調用返回的函數的時候,函數裏面的this將會指向給bind()函數傳入的參數,並在調用新函數時,將給定參數列表做爲原函數的參數序列的前若干項, 因此 bind()函數很是適合在事件回調的時候修改this 指向, 有React 經驗的朋友應該會有更深的感覺。app

call()

var dist = 'Beijing';

function greet(name, hometown) {
  var word =  `Welcome ${name} from ${hometown} to ${this.dist}!`
  console.log(word);
}

var obj1 = {
  dist: 'Chengdu'
};

greet.call(obj1, "Tom", "Dallas");  // Welcome Tom from Dallas to Chengdu!

greet("Jerry", "Houston"); // Welcome Jerry from Houston to Beijing!

由於greet.call(obj) 傳入了obj1做爲第一個參數,因此在 greet()函數執行時, this指向 obj1。其他的參數就將做爲參數傳給greet()函數。
當沒有使用call()而直接調用greet()時, this指向 window對象.異步

apply()

var dist = 'Beijing';

function greet(name, hometown) {
  var word =  `Welcome ${name} from ${hometown} to ${this.dist}!`
  console.log(word);
}

var obj1 = {
  dist: 'Chengdu'
};

var args = ["Tom", "Dallas"];
greet.apply(obj1, args);  // Welcome Tom from Dallas to Chengdu!

greet("Jerry", "Houston"); // Welcome Jerry from Houston to Beijing!

apply()函數和call()函數很是的類似,第一個參數都用來設置目標函數運行時的this指向。 惟一的區別就是 apply()的第二個參數接受一個數組, 其餘表現則同樣。函數

bind()

var dist = 'Beijing';

function greet(name, hometown) {
    var word = `Welcome ${name} from ${hometown} to ${this.dist}!`;
    console.log(word);
}

var obj1 = {
    dist: 'Chengdu',
};

var obj2 = {
    dist: 'Chongqing',
};

var greet1 = greet.bind(obj1, 'Tom', 'Dallas');
var greet2 = greet.bind(obj2, 'Spike', 'San Antonio');

greet('Jerry', 'Houston');

greet1();
setTimeout(function() {
    greet2();
}, 1000);

這個例子會更加複雜一點, 輸出結果以下:this

Welcome Jerry from Houston to Beijing!
  Welcome Tom from Dallas to Chengdu!
  Welcome Spike from San Antonio to Chongqing!

在上面例子中, bind()函數並不會當即執行目標函數, 而是返回了一個函數的拷貝,但this會指向bind()的第一個參數,其他傳給bind()的參數都會按順序傳給返回的函數。咱們就能夠異步調用這個函數返回值了。可是須要注意的是,bind()方法返回的函數拷貝在使用 new 操做時, 第一個參數是會被忽略的。prototype

那麼新的問題又來了, 若是在調用返回的函數拷貝的時候, 又傳入了新的參數, 會發生什麼呢, 只有再寫一個例子試試了。code

var obj1 = {
    dist: 'Chengdu',
};

function greet(name, hometown) {
    console.log(Array.prototype.slice.call(arguments));
    var word = `Welcome ${name} from ${hometown} to ${this.dist}!`;
    console.log(word);
}

var greet1 = greet.bind(obj1, 'Tom', 'Dallas');

greet1('Jerry', 'Houston');

輸出的結果爲:對象

[ "Tom", "Dallas", "Jerry", "Houston" ]
Welcome Tom from Dallas to Chengdu!

結果證實兩個地方傳入的參數都會被傳給目標函數,函數拷貝調用時傳入的參數會追加在bind()函數調用時傳入的參數後面。事件

以上就是全部關於 call(), apply()bind() 三個函數的實例了。你們有什麼疑問建議留言討論。ip

本文始發於 bbwho.com 站點
相關文章
相關標籤/搜索