javascript - 带有箭头函数的事件处理程序如何实现上下文绑定(bind)

标签 javascript reactjs this

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

看看这两段代码:

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 自动绑定(bind)(通过 React)到组件实例
  • 第一个因此成功,
  • 第二个失败,因为es6中的类方法没有绑定(bind)组件实例,从而将方法中的this解析为undefined

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

  1. 按钮点击处理程序是一个匿名的arrow 函数,因此每当我在其中引用this 时,它都会从环境中获取this (在本例中来自 render())
  2. 然后调用 goToStore 方法,这是一个常规函数。
  3. 因为调用似乎符合隐式绑定(bind)规则 (object.function()) object 将是上下文对象,在此类函数调用中将使用它作为这个
  4. 因此,在 goToStore 方法中,词法选取的 this(用作上下文对象)将正确解析为组件实例

我觉得 3. 和 4. 在这里不是这种情况,因为它适用于 2. 情况:

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

还有 this 上下文对象。

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

最佳答案

正如 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) 
    }

现在在这个匿名函数中 this 指的是渲染函数的词法上下文,它又指的是 React 类实例。

现在

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

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

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

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

function foo() {
    alert(this);
}

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

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

所以在这里,由于函数的调用方式类似于 this.goToStore(),this 内部将引用 React 组件的上下文。

然而,当您编写 onClick={this.goToStore} 时,该函数并未执行,而是将其引用分配给 onClick 函数,稍后调用它,导致 this 在函数内部未定义,因为函数在 window 对象的上下文中运行。

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

goToStore = (e) => {

}

查看文档以获取有关 this 的更多详细信息

关于javascript - 带有箭头函数的事件处理程序如何实现上下文绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47679673/

相关文章:

javascript - 从 Javascript 中的另一个函数调用函数时保留 "this"

javascript - 构造函数中的箭头函数和 this

javascript - 除非输入有文本,否则阻止页面导航

javascript - 从 url 中删除管理员

javascript - axios 不会分别返回响应和错误

javascript - 元素类型无效 : expected a string (for built-in components) or a class/function (for composite components) but got: undefined React

c# - 当使用 'this'关键字时系统如何知道使用什么?

javascript - Highcharts:将位于相对两侧的两个系列水平对齐到同一 x 轴

javascript在另一个if语句中获取对象

javascript - react Hook : What/Why `useEffect` ?