在学习JS和React的同时,我在教程中遇到了令人困惑的差异。
我将通过示例拆分以下问题。我了解常规函数和这种上下文的绑定,这仅仅是箭头函数,以及我如何看待它们使用/声明它们的方式令人困惑。
请不要仅仅参考重复的内容,因为我在使我感到困惑的教程中发现了矛盾的答案,因此寻找可以简单理解的真理来源。与以下问题和示例相关的答案会更好。
1-我看到了一些示例,其中的一个教程说'this'的值将是window,因为arrow函数是从global / window范围继承的,但是我也看到了一些教程,他们说它将从类上下文-哪个正确?如果可以的话,请解释。
class MyClass {
value = 'Hello World!'
clickHandler = () => { console.log(this.value) };
}
2-这个问题有2个部分- i-为什么语法clickHandler =()=>而不是clickHandler()=>
我之所以这样问,是因为我读取的类方法可以用'functionName(){}'定义,所以箭头函数为什么将方法名视为变量?
ii-以下代码中的值是什么?与问题1相同,我想这是指窗口对象还是类?
class Foo extends React.Component {
constructor() {
}
clickhandler = () => {
console.log("you clicked me!!")
}
render() {
return(
<div>
<button onClick={this.clickhandler}> // => CALLBACK
3-在这里我看到事件处理程序是一个内联函数,但是它看起来像是由于末尾的()而被调用的,有时如下面的代码片段所示,您可以看到仅给出了函数名没有括号,他们不应该也在那里吗?
class MyComponent extends React.Component {
showValue() {
console.log(this.props.value);
}
render() {
return (
<button onClick={() => this.showValue()}>Do Something</button>
);
}
}
-------------------------------------------
showValue() {
console.log(this.props.value);
}
render() {
return (
<button onClick={this.showValue}>Do Something</button>
);
}
答案 0 :(得分:2)
为什么语法clickHandler =()=>而不是clickHandler()=>
foo () => ...
语法对ES6类无效,并且此概念没有意义。 foo() {...}
是原型方法的语法糖:
function Class() {}
Class.prototype.foo = function () {
// this instanceof Class === true
}
如果Class.prototype.foo
是箭头,则此操作无效; this
将从定义Class
的范围中检索:
// this === undefined
Class.prototype.foo = () => {
// this === undefined
}
foo = () => ...
是class field语法,这是第3阶段建议,不是ES6的一部分。
class Class {
foo = () => {
// this instanceof Class === true
}
}
是以下语言的语法糖:
class Class {
constructor() {
// this instanceof Class === true
this.foo = () => {
// this instanceof Class === true
}
}
}
我看过一些示例,其中的一个教程说此箭头的值将是window,因为arrow函数是从global / window范围继承的,但是我也看过一些教程说它们将从类context / scope继承这个值-正确吗?
箭头功能从封闭范围获得词法this
。如果在全局范围内定义了箭头,则this
是window
,在ES模块范围内是undefined
。
在上面的示例中,在类构造函数作用域中定义了一个箭头,this
是类实例。
在这里,我看到事件处理程序是一个内联函数,但是它似乎由于结尾处的()而被调用,有时就像在下面的摘录中一样,您可以看到仅给出了函数名而没有括号,他们不应该也在那里吗?
回调函数应作为onClick
道具来传递。 this.showValue()
调用一个函数并从中返回一个值。除非值也是函数,否则就地调用onClick={this.showValue()}
之类的方法是不正确的。
onClick={this.showValue}
将类方法作为回调传递。由于showValue
是未绑定到正确的this
上下文的原型方法,因此回调将在错误的上下文中执行(问题在this question中进行了说明),而onClick={() => this.showValue()}
通过包装器函数作为回调,并在正确的上下文中执行showValue
。
答案 1 :(得分:0)
1- this
是指当前范围。在MyClass
中,这是指类实例。
因此,答案都是正确的。在全局范围内,这是指窗口,在myclass
内部,是指类。
2-正如您可能在箭头函数中注意到的那样,无需将函数与类绑定,因此语法有所不同。
3- onClick={() => this.showValue()}>Do Something</button>
:每次单击触发事件时创建一个函数。在某些情况下,当您要将多余的args从组件渲染传递到事件处理程序时,这很有用。
onClick={() => this.showValue(event, id, name)}>Do Something</button>
但通常情况下使用onClick={this.showValue}>Do Something</button>
,您会在触发事件时调用处理程序,而无需每次都创建新函数。
但是它如何识别处理程序?通过绑定,this
可以识别范围内的内容,因为您在范围showValue
内调用它