类和箭头函数以及此

时间:2019-02-23 14:51:49

标签: javascript reactjs this es6-class arrow-functions

在学习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>
    );
  }

2 个答案:

答案 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。如果在全局范围内定义了箭头,则thiswindow,在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内调用它