所有的函数都从Function.prototype中继承了call, apply 和 bind 方法
这些方法可以设置函数内部的this值
初始化
npm init -y
安装ts
npm install -g typescript ( linux 或者 mac 如果出现权限错误需要sudo )
先定义一个Student类, 包含两个属性name和age, 实际上我只使用了name
export class Student {
public name: string;
public age: Int16Array;
public hello() {
console.log("hello, i am " + this.name);
}
}
然后写一个main类
import { Student } from "./Student";
const stu: Student = new Student();
stu.name = "lizhe";
stu.hello();
使用tsc命令进行编译会得到两个js文件
tsc main.ts
然后使用node命令直接运行这个js
lizhedeMacBook-Pro:src lizhe$ node main.js
hello, i am lizhe
lizhedeMacBook-Pro:src lizhe$
然后我们开始进行第一个例子call方法
修改main.ts文件内容为
import { Student } from "./Student";
const stu: Student = new Student();
stu.name = "lizhe";
stu.hello();
stu.hello.call(null);
请注意最后一行, call函数的第一个参数为this引用, 这里直接写了null之后会使用 null来作为this的值并调用this.name, 所以会报错
运行结果为

如果要使用apply方法, 参数表需要变为一个数组
stu.hello.call(this,”a”,”b”);
stu.hello.apply(this, [“a”,”b”]);
其调用结果是一样的
最后是bind函数, bind函数可以在非调用情况下(上面两个都是调用函数时改变)改变this的引用
下面的例子中我们创建了两个实例, 一个 lizhe 一个 tom, 一旦使用了bind函数之后, 就不能再使用call和apply方法来覆盖它绑定的值
import { Student } from "./Student";
const stu: Student = new Student();
stu.name = "lizhe";
stu.hello();
const tom: Student = new Student();
tom.name = "Tom";
const newHello = stu.hello.bind(tom);
newHello();
newHello.call(null);
newHello.apply(null, []);

这里有一个点需要提一下,就是箭头函数 如果hello函数是一个箭头函数, 调用的时候this永远指向类实例
首先把hello写
public hello = () => {
console.log("hello, i am " + this.name);
};
会得到

onClick={this.handleClick(i)}
函数在render的时候已经执行了, 可能会出现递归调用
onClick = {this.handleClick}
这种写法无法传参
onClick = {()=> this.handleClick(i)}
这样闭包 使用一个匿名函数, 让这个匿名函数去调用handleClick, 并且传递 i