最近学习,浏览代码,经常看到组件里面绑定事件时,有两种用法,
不知道两者有啥关系 /区别,或者应该在什么情况下使用哪种,特来请教一下。
class A extends React.Component {
handleClick(parameter) {
}
handleCheck = () => {
}
render() {
return (
<component
onClick={this.handleClick.bind(this, parameter)}
onCheck={this.handleCheck}
>
</component>
)
}
}
如上所未,class 内的成员函数,有两种写法,一种普通的,一种 arrow function
同样,在组件属性指定时,有的需要调用.bind(this),有的就是直接引用函数了。
这两种用法,有啥不一样?
谢谢!
1
ChanKc 2020-07-15 17:14:36 +08:00 via Android
1 希望函数内的 this 和函数外的 this 都指向同一个对象,用箭头函数。希望写成构造函数,就要携程普通函数,但是这个时候你可以直接用 class 的写法,更现代更易于阅读
2 啥时候都不要用 bind,除了以下两个情况:一是把 ArrayLike 且非 iterable 的东西转数组或调用数组的方法,二是对使用 Object.create(null)生成的对象使用 Object 的原型上的方法 |
2
ChanKc 2020-07-15 17:28:22 +08:00 via Android
噢你说的是 bind,好像就更没有用了
我说的主要适用于 call 和 apply,不过 bind 和它们也有类似的地方 在现代的 JavaScript 里真的没什么用了 |
3
xbrave 2020-07-15 17:54:15 +08:00
建议阅读 React 文档官网上的 handling Events 这一节:https://reactjs.org/docs/handling-events.html
You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called. This is not React-specific behavior; it is a part of how functions work in JavaScript. Generally, if you refer to a method without () after it, such as onClick={this.handleClick}, you should bind that method. If calling bind annoys you, there are two ways you can get around this. If you are using the experimental public class fields syntax, you can use class fields to correctly bind callbacks |
4
yazoox OP |
5
mingtianjiayou 2020-07-15 18:02:50 +08:00
这俩是 js 中绑定 this 的两种方式:
public class fields 语法,this 已经绑定,可以直接调用 ```js handleClick = () => { console.log('this is:', this); } ``` 这种需要,调用时用 bind 手动绑定 this ```js handleClick(parameter) { } ``` 还有一种,也可以在回调中使用箭头函数 ```jsx <button onClick={() => this.handleClick()}> Click me </button> ``` 目的都是为了确保函数内可以正确的访问到 this,除了写法上的,感觉没有什么区别。。 附个 react 的链接 https://zh-hans.reactjs.org/docs/handling-events.html |
6
ChanKc 2020-07-15 18:06:26 +08:00 via Android
@yazoox 所以有人发明了 this-free 编程范式,Douglas Crockford 就很喜欢这种,可以完全不用 this 在 JS 中编程。但是如果你用了用到 this 的库就几乎不可避免要学习相关的知识
|
7
ChanKc 2020-07-15 18:09:35 +08:00 via Android
#6 具体可以看 Douglas Crockford 的书 How JavaScript Works 第十七章 How Class Free Works
|
8
yazoox OP @ChanKc @mingtianjiayou 对于这句话,我有点疑问
“ In JavaScript, class methods are not bound by default.". 如果这样的话,那一个标准的 class 下面,自己的成员函数,都不能互相调用了? e.g. 下面这个 myclass,没有显示的 bind A&B,但是,实际上是可以这么用的。 class myclass { function A() {} function B() { this.A(); // 实际上,这么用是没有问题的呢。 } } |
10
mingtianjiayou 2020-07-15 18:28:29 +08:00
@yazoox 要看你是怎么调用 B 的,普通函数内的 this 取决于它的执行环境,附个链接 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/this
|
11
ChanKc 2020-07-15 18:28:36 +08:00 via Android
@yazoox 我想了一下,class methods 指的是原型链上的方法,而不是对象上的方法。我没写过 react,我猜是 react 只能调用对象上的方法?
你写的 myclass,A 和 B 应该都是 myclass.prototype 这个对象的方法 |
12
ChanKc 2020-07-15 19:00:19 +08:00
#8 @yazoox
参考以下代码 class Adder { constructor(a, b) { this.a = a; this.b = b; } add() { return this.a + this.b } } let a = new Adder(1, 3); a.add(); // 4 Object.setPrototypeOf(a, null); a.add(); // Uncaught TypeError: a.add is not a function class AnotherAdder { constructor(a, b) { this.a = a; this.b = b; this.add = this.add.bind(this); } add() { return this.a + this.b } } let b = new AnotherAdder(1, 3); b.add(); // 4 Object.setPrototypeOf(b, null); b.add(); // 4 |
13
IsaacYoung 2020-07-15 19:43:41 +08:00
class arrow function 原型上没有这个函数
bind 的方式有 |
14
KuroNekoFan 2020-07-15 20:39:06 +08:00 via iPhone
this free is good,就应该用且仅用参数来传递信息
|
15
azcvcza 2020-07-16 09:15:55 +08:00
|
16
ChanKc 2020-07-16 12:57:19 +08:00
另外主楼里的 handleCheck 和 handleClick 方法的一大区别是后面的等号
handleC |
17
ChanKc 2020-07-16 13:00:25 +08:00
#16 手抖变成了回复……
另外主楼里的 handleCheck 和 handleClick 方法的一大区别是后面的等号 handleCheck = () => {} 这句实际上是 https://github.com/tc39/proposal-class-fields 的语法,因此方法是在对象上而不是在原型上,因此不需要在构造器里面再 bind handleCheck |
18
cxyct2 2020-07-16 14:51:35 +08:00 via Android 1
class A {
constructor (props) { this.props = props this.printProps = this.printProps } printProps = function () { return this.props } } (function () { const a = new A('haha') console.log(a.printProps()) const fun = a.printProps console.log(fun()) })(); 如果不绑 this 的话 a.printProps()不会报错,但是 fun()会报错 |