所以我正在尝试学习 JavaScript 和/或 react 并且对理解 .bind(this) 有点困惑构造函数。不过,我现在想明白了,只是想知道,
为什么有人会在 JavaScript 中使用绑定(bind)而不是箭头函数?
(或在 onClick 事件中)。
请参阅下面的代码示例。
绑定(bind)方法确保 clickEvent 函数中的 this 引用类:
class Click extends react.Component {
constructor(props) {
super(props)
this.clickEvent = this.clickEvent.bind(this);
}
render = () => (
<button onClick= { this.clickEvent } > Click Me < /button>
)
clickEvent() { console.log(this) } // 'this' refers to the class
}
但是下面的方法也引用了这个类:
class Click extends react.Component {
render = () => (
<button onClick= {() => { this.clickEvent() }}> Click Me < /button>
)
clickEvent() { console.log(this) } // 'this' refers to the class
}
最佳答案
首先,让我们从每种技术的例子开始吧!
但差异更多地与 JavaScript 语言本身有关。
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props)
this.clickHandler = this.clickHandler.bind(this);
}
clickHandler() {
console.log( this )
}
render() {
return <button onClick={this.clickHandler}>Click Me</button>
}
}
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props)
}
clickHandler = () => {
console.log( this )
}
render() {
return <button onClick={this.clickHandler}>Click Me</button>
}
}
在 public-class-field 上使用 Arrow-function 更易读, 因为更少的代码行, 但请记住,使用箭头函数会影响两件事:
首先是内存和性能;当您使用类字段定义函数时,您的整个方法驻留在类的每个实例而不是原型(prototype)上,但使用绑定(bind)技术,只是一个小callback 存储在每个实例上,它调用存储在原型(prototype)上的方法。
第二个可能受到影响的是您编写单元测试的方式。 您将无法使用组件原型(prototype)来 stub 函数调用,如下所示:
const spy = jest.spyOn(MyComponent.prototype, 'clickHandler');
// ...
expect(spy).toHaveBeenCalled();
必须找到另一种方法来 stub 该方法,例如,在 props 中传递虚拟回调,或者检查 状态改变。
计算机真的很擅长阅读代码;你不应该为此担心。 您可能需要考虑使用类属性箭头函数使您的代码更易于阅读。
如果您想同时保持人类可读性和性能,请考虑使用 plugin-transform-arrow-functions插件(尽管 v7.2.0 caused problems 对我来说),只需运行 npm i --save-dev @babel/plugin-transform-arrow-functions 并将其添加到您的“babel.config.js”或“.babelrc”文件,例如:
{
"presets": ["module:metro-react-native-babel-preset"],
"plugins": [
["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": false }],
["@babel/plugin-transform-arrow-functions", { "spec": true }]
]
}
或者你可以使用类似 auto-bind decorator 的东西,这会将上面的例子变成:
import React from 'react';
import { boundMethod as bind } from 'autobind-decorator';
class MyComponent extends React.Component {
constructor(props) {
super(props)
}
@bind
clickHandler() {
console.log( this )
}
render() {
return <button onClick={this.clickHandler}>Click Me</button>
}
}
Note that it's unnecessary to put
@bindon every function. You only need to bind functions which you pass around. e.g.onClick={this.doSomething}Orfetch.then(this.handleDone)
关于javascript - 绑定(bind) vs 箭头函数(在 JavaScript 中,或用于响应 onClick),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50375440/
在railstutorial中,作者为什么选择使用这个(代码list10.25):http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-usersnamespace:dbdodesc"Filldatabasewithsampledata"task:populate=>:environmentdoRake::Task['db:reset'].invokeUser.create!(:name=>"ExampleUser",:email=>"example@railstutorial.org",:passwo
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
它不等于主线程的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!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie
当我使用has_one时,它工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290
如何在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中能不能做到类似的简洁?我可以只