咱們知道能夠用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 站點