我知道 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>
}
}
我知道的是:
render() 方法中的 this 自动绑定(bind)(通过 React)到组件实例this解析为undefined据我所知,理论上在第一个版本中会发生以下情况:
this 时,它都会从环境中获取this (在本例中来自 render())goToStore 方法,这是一个常规函数。object.function()) object 将是上下文对象,在此类函数调用中将使用它作为这个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/
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
我正在尝试在Rails上安装ruby,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).