在咱们平常开发当中,咱们写一个组件,常常遇到须要传递一个方法给点击事件等等,那么咱们常常是怎么作的呢?javascript
class Item extends Component { jump = () => { this.setState({ xxx: true }); }; render() { return ( <div onClick={this.jump}>跳转啰</div> ); } }
如上代码,由于点击回调使用了this,为了绑定this,使用了箭头函数。或者不使用箭头函数了,用bind进行绑定。java
class Item extends Component { jump() { this.setState({ xxx: true }); } render() { // 在render里进行bind return ( <div onClick={::this.jump}>跳转啰</div> ); } }
亦或者是这样函数
class Item extends Component { constructor() { // 在初始化就绑定 this.jump = this.jump.bind(this); } jump() { this.setState({ xxx: true }); } render() { return ( <div onClick={this.jump}>跳转啰</div> ); } }
是否是!是否是!我相信以上3种绑定方式起码有90%的占有率!!!this
咱们一个一个状况来分析。prototype
咱们知道使用箭头函数的时候,他实际上该方法是放在了实例上面,而不是prototype上面,举个例子。code
class A { a = '1' func1() { } func2 = () => {}; } const a = new A();
你们能够试试在控制台看一下a究竟长什么样子,如无心外他应该是介个样子的。继承
{ a: '1', func2: () => {}, __proto__: { func1: function() {} } }
那么咱们想一想,假设咱们在一个列表item组件上使用箭头函数,实际上他的实例是怎么样的。
就是每个实例上的箭头函数都不是在prototype公用的而是本身建立一个函数!那么相似在商品列表种的商品item,大家如今还以为使用箭头函数绑定this吗?事件
相信你们都使用过了修饰器了,那么你们想一想,修饰器 能修饰箭头函数吗?
答案是不能!
修饰器的输入是什么ip
function boundMethod(target, key, descriptor) { return { // 新的descriptor }; }
其中target是实例自己,key是被修饰的key,descriptor是该属性的描述。
咱们来看一下修饰prototype上的方法跟修饰箭头函数有什么不一样。开发
const testDes = function() { return function(target, name, descriptor) { return { ...descriptor, value: function() { console.log('descaaaa') descriptor.value(); } }; }; }; class A { @testDes(1) func1() { } @testDes(1) func2 = () => { } } var a = new A(); a.func1(); a.func2(); console.log(a)
以上例子,咱们发现只有a.func1()=
才会有打印修饰的字符,修饰器是不能修饰prototype上不存在的属性的。
你们想想,若是一个类中使用了箭头函数,那么这个类能够被继承吗?
答案就是不能够了。
由于箭头函数并不声明在prototype上,因此该方法不能在子类上被使用,致使一种奇怪的错觉。
其实这个问题比较明显,咱们都知道bind方法是返回一个新的方法,就是在每次render的时候都会建立新的函数,销毁上一次的函数。在render触发比较频繁的时候,就会有很是多没有必要的建立销毁开销。
这个方式其实跟箭头函数有类似之处,就是在实例自己再次赋值一个经过bind的方法,也就是多个实例之间各自都有一个方法,而且该类prototype上的方法就冗余了。
既然以上的绑定this都或多或少有很差的地方,可是实际使用咱们常常须要绑定this,那么怎么绑定this才是最好的呢?
答案就是使用修饰器进行绑定。
你们能够看一下autobind-decorator
这个库,很是简单,使用修饰器进行绑定,就是直接在prototype上进行更改,多个实例共享没问题,继承也没毛病,该方法依旧能够被再次修饰。完美了!
看到这篇文章的你,知道怎么绑定this了吗?