在咱們平常開發當中,咱們寫一個組件,常常遇到須要傳遞一個方法給點擊事件等等,那麼咱們常常是怎麼作的呢?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了嗎?