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

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

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

call 與 apply 調用參數不同

不同之處在於調用apply函數時,參數可以使用數組; call要求明確列出參數。

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

更多請參閱MDN的文檔。

僞語法:

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

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

示例代碼:

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"]); // 使用展開語法

搞這麼複雜,直接調用函數不好嗎?

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

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章