致电并申请

函数有两个内置方法,允许程序员以不同的方式提供参数和 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"