所以我正在尝试学习 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
语言本身有关。
绑定(bind):
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
@bind
on 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/