1. call和apply
call和apply方法非常相似,都是先设置函数中的this操作符的值,并且执行这个函数。
区别:
- apply以数组形式接受传递给函数的参数
- call以单个分开参数的形式
例子:
class Person {
public name: string;
public surname: string;
constructor(name: string, surname: string) {
this.name = name;
this.surname = surname;
}
public greet(city: string, country: string) {
// 使用this操作符访问实例的name和surname属性
var msg = `Hi, my name is ${this.name} ${this.surname}. `;
msg += `I'm from ${city} (${country}).`;
console.log(msg);
}
}
var person = new Person("Fourteen", "Zhang");
person.greet("Shijiazhuang", "China");
// Hi, my name is Fourteen Zhang. I'm from Shijiazhuang (China).
// 通过call和apply函数调用该方法
person.greet.call(person, "Shijiazhuang", "China");
person.greet.apply(person, ["Shijiazhuang", "China"]);
var valueOfThis = { name: "Fourteen", surname: "Zhang" };
person.greet.call(valueOfThis, "Shijiazhuang", "China");
person.greet.apply(valueOfThis, ["Shijiazhuang", "China"]);
// Hi, my name is Fourteen Zhang. I'm from Shijiazhuang (China).
2. bind
bind方法也可以设置this操作符的值,但不执行它。
注意:
- 调用函数的bind方法时,返回一个和原函数具有相同函数体和作用域的新函数
- 函数体内部的this操作符指向的值,已被永久地改变为传递给bind方法的第一个参数,不会改变
例子:
var person = new Person("Fourteen1", "Zhang");
var greet = person.greet.bind(person);
greet.call(person, "Hebei", "China");
greet.apply(person, ["Hebei", "China"]);
// Hi, my name is Fourteen1 Zhang. I'm from Shijiazhuang (China).
greet.call(null, "Hebei", "China");
greet.apply(null, ["Hebei", "China"]);
// Hi, my name is Fourteen1 Zhang. I'm from Hebei (China).
var valueOfThis = { name: "Fourteen2", surname: "Zhang" };
greet.call(valueOfThis, "Hebei", "China");
greet.apply(valueOfThis, ["Hebei", "China"]);
// Hi, my name is Fourteen1 Zhang. I'm from Hebei (China).
一旦使用bind方法为一个函数内的this操作符进行了绑定,就不能再覆盖它:
var valueOfThis = { name: "Fourteen3", surname: "Zhang" };
var greet = person.greet.bind(valueOfThis);
greet.call(valueOfThis, "Hebei", "China");
greet.apply(valueOfThis, ["Hebei", "China"]);
// Hi, my name is Fourteen1 Zhang. I'm from Hebei (China).