理解JavaScript中的call,apply和bind方法

前言

js中的call(), apply()bind()Function.prototype下的方法,都是用於改變函數運行時上下文,最終的返回值是你調用的方法的返回值,若該方法沒有返回值,則返回undefined。這幾個方法很好地體現了js函數式語言特性,在js中幾乎每一次編寫函數式語言風格的代碼,都離不開call和apply,可以熟練運用它們,是真正成爲一名jser程序員的重要一步。javascript

apply()

使用 apply, 你能夠繼承其餘對象的方法:java

var max = Math.max.apply(null, [1, 2, 3, 4, 5]);
console.log(max); // 輸出5

注意這裏apply()的第一個參數是null,在非嚴格模式下,第一個參數爲null或者undefined時會自動替換爲指向全局對象,
apply()的第二個參數爲數組或類數組。程序員

call()

call()apply()的一顆語法糖,做用和 apply() 同樣,一樣可實現繼承,惟一的區別就在於call()接收的是參數列表,而apply()則接收參數數組。數組

var max = Math.max.call(null, 1, 2, 3, 4, 5);
console.log(max); // 輸出5

bind()

bind()的做用與call()apply()同樣,都是能夠改變函數運行時上下文,區別是call()apply()在調用函數以後會當即執行,而bind()方法調用並改變函數運行時上下文後,返回一個新的函數,供咱們須要時再調用。app

var person = {
  name: 'person',
  getName: function() {
    return this.name;
  }
}
var boy = {
   name: 'twy'
}
// bind()返回一個新函數,供之後調
var getName = person.getName.bind(boy);

// 如今調用
console.log(getName());    // 輸出wy

apply()模擬實現bind()函數

Function.prototype.bind = function(context) {
  // 保存調用函數的引用,這裏是getName()
  var self = this;
  // 返回一個新函數
  return function(){
    return self.apply(context, arguments);
  }
}
var person = {
  name: 'twy'
}
var getName = function(){
  console.info(this.name);
}.bind(person);
// 執行bind()方法內返回的新函數
getName();

在返回的新函數內部,self.apply(context, arguments)纔是執行原來的getName函數,至關於執行getName.apply(person);this

如何選用

  • 若是不須要關心具體有多少參數被傳入函數,選用apply()
  • 若是肯定函數可接收多少個參數,而且想一目瞭然表達形參和實參的對應關係,用call()
  • 若是咱們想要未來再調用方法,不需當即獲得函數返回結果,則使用bind();

總結

  • call()apply()bind()都是用來改變函數執行時的上下文,可藉助它們實現繼承;
  • call()apply()惟一區別是參數不同,call()apply()的語法糖;
  • bind()是返回一個新函數,供之後調用,而apply()call()是當即調用。
相關文章
相關標籤/搜索