函數原型中的 call 和 apply 方法的區別

call, apply都屬於Function.prototype的方法

它們是在 JavaScript 引擎內在實現的,由於屬於Function.prototype,因此每一個Function對象實例,也就是每一個方法都有call, apply屬性。它們的做用同樣,只是使用方式不一樣。git

call 與 apply 調用參數不一樣

不一樣之處在於調用apply函數時,參數能夠使用數組; call要求明確列出參數。es6

助記法: Apply 的A表示 Array, 即數組, 而 Call 的 C 表示 Comma, 即逗號。

更多請參閱MDN的文檔。github

僞語法:數組

theFunction.apply(valueForThis, arrayOfArgs)
theFunction.call(valueForThis, arg1, arg2, ...)

從ES6開始,還有展開spread數組與該call功能一塊兒使用的可能性,你能夠在這裏看到兼容性。app

示例代碼:函數

function theFunction(name, profession) {
    console.log("My name is " + name + " and I am a " + profession +".");
}
theFunction("John", "fireman");
theFunction.apply(undefined, ["Susan", "school teacher"]);
theFunction.call(undefined, "Claude", "mathematician");
theFunction.call(undefined, ...["Matthew", "physicist"]); // 使用展開語法

搞這麼複雜,直接調用函數很差嗎?

主要是爲了模擬面向對象,對狀態進行封裝的同時, 不一樣實例能夠有不一樣的內部狀態,如:this

var module = {
  x: 42,
  getX: function() {
    return this.x;
  }
}

var unboundGetX = module.getX;
console.log(unboundGetX()); // 函數在全局範圍內調用,this=window
// 會輸出: undefined, 由於window下沒有定義x
unboundGetX.call(module) //輸出 42, 或使用 bind 也有一樣的效果
var module1 ={
   x:123,
   getX: unboundGetX  //this 變爲module1
}
module1.getX() //返回123
相關文章
相關標籤/搜索