致电并申请
函数有两个内置方法,允许程序员以不同的方式提供参数和 this
变量:call
和 apply
。
这很有用,因为对一个对象(它们是其属性的对象)进行操作的函数可以重新用于对另一个兼容对象进行操作。另外,参数可以一次性作为数组给出,类似于 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"