致電並申請

函式有兩個內建方法,允許程式設計師以不同的方式提供引數和 this 變數:callapply

這很有用,因為對一個物件(它們是其屬性的物件)進行操作的函式可以重新用於對另一個相容物件進行操作。另外,引數可以一次性作為陣列給出,類似於 ES6 中的 spread(...)運算子。

let obj = {
    a: 1,
    b: 2,
    set: function (a, b) {
        this.a = a;
        this.b = b;
    }
};

obj.set(3, 7); // normal syntax
obj.set.call(obj, 3, 7); // equivalent to the above
obj.set.apply(obj, [3, 7]); // equivalent to the above; note that an array is used

console.log(obj); // prints { a: 3, b: 5 }

let myObj = {};
myObj.set(5, 4); // fails; myObj has no `set` property
obj.set.call(myObj, 5, 4); // success; `this` in set() is re-routed to myObj instead of obj
obj.set.apply(myObj, [5, 4]); // same as above; note the array

console.log(myObj); // prints { a: 3, b: 5 }

Version >= 五

除了 call()apply() 之外,ECMAScript 5 引入了另一種名為 bind()方法,以明確地將函式的 this 值設定為特定物件。

它的行為與其他兩個完全不同。bind() 的第一個引數是新函式的 this 值。所有其他參數列示應在新函式中永久設定的命名引數。

function showName(label) {
    console.log(label + ":" + this.name);
}
var student1 = {
     name: "Ravi"
};
var student2 = {
     name: "Vinod"
};

// create a function just for student1
var showNameStudent1 = showName.bind(student1);
showNameStudent1("student1"); // outputs "student1:Ravi"

// create a function just for student2
var showNameStudent2 = showName.bind(student2, "student2");
showNameStudent2(); // outputs "student2:Vinod"

// attaching a method to an object doesn't change `this` value of that method.
student2.sayName = showNameStudent1;
student2.sayName("student2"); // outputs "student2:Ravi"