ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

javascript – 带箭头函数的事件处理程序如何实现上下文绑定

2019-06-07 18:20:34  阅读:209  来源: 互联网

标签:javascript this reactjs


我知道这个绑定的一般理论(函数调用站点重要,隐式,显式绑定等等)和解决React中这个绑定问题的方法所以它总是指向我想要的东西(绑定在构造函数,箭头函数等),但我正在努力获得内部机制.

看看这两段代码:

class demo extends React.component {
  goToStore(event) {
    console.log(this)
  }

  render() {
    <button onClick={(e) => this.goToStore(e)}>test</button>
  }
}

class demo extends React.component {
  goToStore(event) {
    console.log(this)
  }

  render() {
    <button onClick={this.goToStore}>test</button>
  }
}

我所知道的是:

>在两个版本中,我们在goToStore方法中成功结束,因为render()方法中的this会自动绑定(通过React)到组件实例
>第一个成功因为,
>第二个失败,因为es6中的类方法没有绑定到组件实例,因此在方法中将其解析为undefined

据我所知,在第一个版本的理论中,会发生以下情况:

>按钮单击处理程序是一个匿名箭头函数,所以每当我在其中引用它时,它从环境中获取它(在这种情况下从render())
>然后它调用goToStore方法,这是一个常规函数.
>因为调用似乎符合隐式绑定的规则(object.function())对象将是上下文对象,在这样的函数调用中它将被用作此
>所以,在goToStore方法中,词法上拾取它(用作上下文对象)将正确解析为组件实例

我觉得3.和4.不是这里的情况,因为那样它将适用于2.案例:

<button onClick={this.goToStore}>test</button>

还有这个上下文对象.

在这个特殊情况下,一步一步发生了什么?

解决方法:

正如MDN文档所述

An arrow function does not have its own this; the this value of the
enclosing execution context is used

所以你会想到

onClick={(e) => this.goToStore(e)}

作为一个匿名函数,可以写成

    (e) => { 
         return this.goToStore(e) 
    }

现在,在这个匿名函数中,这引用了render函数的词法上下文,而后者又引用了React Class实例.

现在

上下文通常由调用函数的方式决定.当一个函数作为一个对象的方法被调用时,它被设置为调用该方法的对象:

var obj = {
    foo: function() {
        return this;   
    }
};

obj.foo() === obj; // true

当使用new运算符调用函数来创建对象的实例时,同样的原则也适用.以这种方式调用时,函数范围内的this值将设置为新创建的实例:

function foo() {
    alert(this);
}

foo() // window
new foo() // foo

当作为未绑定函数调用时,这将默认为浏览器中的全局上下文或窗口对象.

所以这里因为函数被调用像this.goToStore()这里面它将引用React组件的上下文.

但是,当您编写onClick = {this.goToStore}时,该函数不会被执行,但是它的引用被分配给onClick函数,该函数随后会调用它,导致函数内部未定义,因为函数在上下文中运行窗口对象.

现在即使onClick = {(e)=> this.goToStore(e)}工作,每当调用render时,就会创建一个新的函数实例.在你的情况下它很容易避免,只需使用箭头函数语法创建函数goToStore.

goToStore = (e) => {

}

有关this的更多详细信息,请查看文档

标签:javascript,this,reactjs
来源: https://codeday.me/bug/20190607/1195579.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有