简体   繁体   English

在课程中使用Ecmascript 6箭头函数作为方法的正确方法是什么?

[英]What is the right way to use Ecmascript 6 arrow functions as methods in classes?

Ecmascript 6 arrow functions seem ideally suited to be used as methods in classes since they are not subject to the calling context messing with the "this" reference. Ecmascript 6箭头函数似乎非常适合用作类中的方法,因为它们不受调用上下文弄乱“this”引用的影响。 I can't see how to use them the way I expect, though. 但是,我无法看到如何以我期望的方式使用它们。 The following is a class which shows two ways I can see to use them: 以下是一个类,它显示了我可以看到使用它们的两种方法:

class Person {

constructor(aName) {
    this.name = aName;
    this.say2 = () => console.log(this.name);
}

say() { console.log(this.name) }

say3() { () => consolve.log(this.name) }

}

Both say2 and say3 will use the new this handling and one should be able to pass them to click handlers, and other functions needing callbacks and not have to worry about the callback being invoked in some what whiich causes "this" to unexpectedly point to something other than the appropriate instance of the object. say2和say3都将使用新的这个处理,并且应该能够将它们传递给单击处理程序,以及需要回调的其他函数,而不必担心在某些导致“this”意外地指向某些东西时调用的回调除了对象的适当实例。

Both say2 and say3 seem awkward, though. 然而,say2和say3似乎都很尴尬。 say2 is defined in the constructor and say3 is really a wrapper around an arrow functions. say2在构造函数中定义,say3实际上是箭头函数的包装器。 I was expecting some sytax which would allow me to replace the say() line with something like 我期待一些sytax可以让我用类似的东西替换say()行

say: () => console.log(this.name)

But as near as I can tell, you cannot do anything like this. 但就我所知,你不能做这样的事情。 So the question is, to use arrow functions as methods is the approach of say2 or say3 reasonable. 所以问题是,使用箭头函数作为方法是say2或say3合理的方法。 Is there a better way? 有没有更好的办法?

In the ES6 grammar, the body of a class may only consist of method definitions , so arrow function expressions are not permitted here. 在ES6语法中, 类的主体可能只包含方法定义 ,因此这里不允许使用箭头函数表达式。 This is a simplified snippet of the relevant portions of the grammar: 这是语法相关部分的简化片段:

ClassBody :
    ClassElementList

ClassElementList :
    ClassElement
    ClassElementList ClassElement

ClassElement :
    MethodDefinition
    static MethodDefinition
    ;

MethodDefinition :
    PropertyName ( StrictFormalParameters ) { FunctionBody }
    GeneratorMethod
    get PropertyName ( ) { FunctionBody }
    set PropertyName ( PropertySetParameterList ) { FunctionBody }

So in your example: 所以在你的例子中:

class Person {

    constructor(aName) {
        this.name = aName;
        this.say2 = () => console.log(this.name);
    }

    say() { console.log(this.name) }

    say3() { () => console.log(this.name) }

}
  • say is a normal method definition, which suffers from the same issues with this binding as normal functions. say是通常的方法定义,这从同样的问题遭受与this结合作为正常功能。 However, you can get around that using bind when you pass it, as in element.addEventListener('click', this.say.bind(this)); 但是,在传递它时可以使用bind来解决这个问题,就像在element.addEventListener('click', this.say.bind(this)); .
  • say2 will work, but you lose the convenience of specifying methods outside of the constructor. say2会起作用,但是你失去了在构造函数之外指定方法的便利。
  • say3 won't work - while it is syntactically valid, it will be parsed as a method, whose body consists of a single arrow function. say3不起作用 - 虽然它在语法上是有效的,但它将被解析为一个方法,它的主体由一个箭头函数组成。 To clarify, say3() { () => console.log(this.name) } and say3() { return () => console.log(this.name) } differ in that the former will do nothing and return undefined , whereas the latter will return an arrow function expression which, when called, will print to the console. 澄清say3() { () => console.log(this.name) }say3() { () => console.log(this.name) }say3() { return () => console.log(this.name) }不同之处在于前者什么都不做并返回undefined ,而后者将返回一个箭头函数表达式,当调用时,它将打印到控制台。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM