我知道的一般理论this
绑定(函数调用的位置有什么事情,隐,显式绑定等)和方法解决这个结合中存在的问题作出反应,因此始终指向我想this
是(在构造函数结合,箭头功能等),但我努力获得的内在机制。
看看这两段代码:
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方法,因为
this
里面的render()
方法自动绑定(通过反应)的组件实例 - 第一个成功正因为如此,
- 第二个出现故障,因为在ES6类方法不绑定到组件实例,从而解决
this
在该方法中undefined
在据我了解的第一个版本的理论,会出现以下情况:
- 按一下按钮处理程序是一个匿名的箭头功能,所以每当我引用
this
在它的内部,它拿起this
从环境(在这种情况下render()
- 然后它调用
goToStore
方法,这是一个普通的功能。 - 因为调用似乎适合隐式绑定(规则
object.function()
object
将是上下文对象,在这种函数调用将被用作this
- 因此,内侧
goToStore
方法词法拿起这(用作上下文对象)将解析到组件实例正确
我觉得3和4是不是这里的情况,因为那将适用于2案例:
<button onClick={this.goToStore}>test</button>
也与this
上下文对象。
什么是在这种特殊情况下究竟发生了,一步一步?
由于MDN文档状态
箭头功能没有自己的这一点; 封闭执行上下文的此值被用来
所以,你会想到的
onClick={(e) => this.goToStore(e)}
作为该可写为一个匿名函数
(e) => {
return this.goToStore(e)
}
现在,这里在这个匿名函数this
指的是渲染功能,这反过来又指阵营类实例的词汇范围内。
现在
上下文最常由函数是如何调用的确定。 当一个函数被调用作为对象的方法,它被设置为被调用的方法的对象:
var obj = {
foo: function() {
return this;
}
};
obj.foo() === obj; // true
同样的原则也调用函数时使用new运算符来创建一个对象的实例应用。 当以这种方式被调用,该函数的范围内的这个值将被设置为新创建的实例:
function foo() {
alert(this);
}
foo() // window
new foo() // foo
当被称为未绑定的功能,这将默认为浏览器在全球范围内或窗口对象。
所以在这里,因为函数被调用像this.goToStore()
这里面将涉及反应组件的上下文。
然而,当你写onClick={this.goToStore}
不执行该功能,但它的一个参考被分配给的onClick功能,然后稍后调用它,从而引起this
给在函数内部未定义作为函数的上下文中运行所述的window
对象。
现在,即使onClick={(e) => this.goToStore(e)}
工作,每当呈现被调用时创建一个新的函数实例。 在你的情况下,它容易避免,只是创建的功能使用箭头函数的语法goToStore。
goToStore = (e) => {
}
检查文档了解更多详细信息, this
在案例1中,如你所说,上下文从环境中捞起。 对于案例2,你要记住,在ES6类语法是刚刚超过其上的JavaScript依赖于实现OOP较为烦琐原型语法句法糖。
原则上,在第二个例子中,你正在做的是这样的:
function demo() {
// this is the constructor
}
demo.prototype.goToStore = function() {
// handler
};
demo.prototype.render = function() {
return React.createElement('button', onClick: this.goToStore);
}
正如你所看到的, onClick
属性正在接收到函数的引用。 每当调用该函数,没有this
将绑定,并且它会在的上下文中运行window
对象。
在旧库之前,现代transpilers的存在,我们用来做这样的事情所有的地方:
function demo() {
// this is the constructor
this.goToStore = this.goToStore.bind(this);
// same for every other handler
}
demo.prototype.goToStore = function() {
// handling code.
};
demo.prototype.render = function() {
// this goToStore reference has the proper this binded.
return React.createElement('button', onClick: this.goToStore);
}
如今,这最后一个例子,我把所有现代transpilers自动处理。 巴贝尔基本上没有在当您使用脂肪箭法语法在任何类的构造函数的自动绑定:
class demo extends Anything {
constructor() {
}
bindedMethod = () => {
// my context will always be the instance!
}
}
有了细微的差别,所有transpilers将定义移动bindedMethod
的构造,在this
将被绑定到运行构造当前实例。
当执行渲染代码, this
指的是组件类,因此它能够以引用正确的功能。 这意味着, element.onClick
指向goToStore
方法。
当调用该函数在浏览器中,它是从HTML元素的上下文中调用(即element.onClick()
所以除非goToStore
方法被绑定到组件类的上下文中,这将继承this
从元件的情况下。
这个答案提供了更多的相关信息,并进一步阅读。