call, apply, bind 方法

所有的函数都从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