起因
某天深夜,朋友发来了一张报错图,问我为什么不 bind this 代码会有报错
demo: codesandbox.io/s/this-bind-ln5vps
普遍解决方案
看报错判断这是当时初学 React 时遇到的问题,一般会通过以下三种方式解决:
- 在
Constructor进行绑定this
- 直接在事件处理函数中
bind this(等价于第一种方法)
- 使用箭头函数(利用箭头函数中的
this引用是定义该箭头函数的上下文这一性质,使其this为当前的Class实例)
分析原因
-
看到报错第一反应是在
changeHandle方法中拿不到Class的this; -
既然能走到函数方法内部,说明已经触发了函数;
-
onClick={this.changeHandle}看到这段代码便有点清楚原因了,这里把this中的changeHandle方法赋值给了onclick,这让我想起了之前看到的this指向的判断题:
let objTest = {
name: 'leo',
sayName() {
console.log(this.name);
},
};
objTest.sayName(); // leo
let a = objTest.sayName;
a(); // undefined
let b = objTest
b.sayName()
第 8 行 把 objTest 的 sayName 方法赋给 a 之后,a 直接指向函数本身,
此时 a( )执行的上下文为全局上下文,所以访问到的 this 为 window。
如果像let b = objTest这种赋值操作,b 其实存储的是 objTest 的内存地址,
调用 b.sayName() 还是会去调用同一个对象上的方法,this 依旧指向的是 objTest。
- 为了证明该结论,于是便使用 babel 转译了该代码:
可以发现在 createElement 方法中给 onclick 赋值了 this.changeHandle ,这也佐证了之前的猜想。而上述两个解决方法一个是提前绑定了该 Class 的 this ,另外一个使用箭头函数也是利用其特性来使 this 指向 Class。
总结
具体行为都是 this 指向问题,之前只是想如何去解决,没有真正意义上研究过深层次原因,于是特此记录。更希望和大家交流~ 🤔
附录
-
Class :es6.ruanyifeng.com/#docs/class
Class 也是
Function的变体?- 准确来说是构造函数的 ES6 写法。 (与构造函数的区别在于所构造的内部方法是不可枚举的)
Constructor()用作构造方法this代表实例对象- 类的数据类型就是函数,类本身就指向构造函数。
- 准确来说是构造函数的 ES6 写法。 (与构造函数的区别在于所构造的内部方法是不可枚举的)
-
this:
- 箭头函数中的
this引用是定义该箭头函数的上下文。而普通函数则是调用其函数的上下文(需要在调用时才能确定)
- 箭头函数中的