JavaScript 中 this
的指向有一些规则,其中可通过 bind
或 arrow function
来绑定 this
的指向。
arrow function 在 ES6 中引入,由于可以绑定 this 的原因,常用来替换普通的匿名函数(function() {}
)。
这两种方式在基于 React 技术中较为广泛地使用,主要是用于事件绑定中。虽然同可绑定 this
,但配合类使用时实际是有差别的。简单来说,基于 arrow function 声明的类属性将无法被继承调用。
class A {
constructor() {
this.bindMethod = this.bindMethod.bind(this);
}
m(p) {
console.log('m', p);
}
bindMethod(p) {
console.log('bindMethod', p);
}
arr = p => {
console.log('arrow', p);
};
}
class B extends A {
m(p) {
console.log('B');
super.m(p);
}
bindMethod(p) {
console.log('B');
super.bindMethod(p);
}
arr = p => {
console.log('B');
super.arr(p); // Error run with compiled code with es2015+stage0
};
}
const a = new A();
a.m(1);
a.bindMethod(2);
a.arr(3);
const b = new B();
b.m(1);
b.bindMethod(2);
b.arr(3);
babel 结果(ES2017 + Stage 0)
上面的 class A
babel 后(把目标设为 ES2017 是为了简化掉实现 class 继承机制的代码),其中,arrow 形式的 class 属性变成了实例属性,而非原型属性,这样就子类将无法通过 super 来调用。
而通过 bind
方式来实现的 this
绑定则依然保留有原型方法。
class A {
constructor() {
this.arr = p => {
console.log("arrow", p);
};
this.bindMethod = this.bindMethod.bind(this);
}
m(p) {
console.log("m", p);
}
bindMethod(p) {
console.log("bindMethod", p);
}
}