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

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

本文关键字:方法 是什么 函数 Ecmascript      更新时间:2023-09-26

Ecmascript 6箭头函数似乎非常适合用作类中的方法,因为它们不受调用上下文干扰"this"引用的影响。不过,我不知道如何按照我期望的方式使用它们。下面是一个类,它显示了我可以看到的两种使用它们的方法:

class Person {
constructor(aName) {
    this.name = aName;
    this.say2 = () => console.log(this.name);
}
say() { console.log(this.name) }
say3() { () => consolve.log(this.name) }
}

say2和say3都将使用新的this处理,应该能够将它们传递给点击处理程序和其他需要回调的函数,而不必担心在某些情况下会调用回调,这会导致"this"意外地指向对象的适当实例之外的其他对象。

say2和say3看起来都很尴尬。say2是在构造函数中定义的,say3实际上是一个围绕箭头函数的包装器。我期待着一些sytax,这将允许我用类似的东西替换say()行

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

但据我所知,你不能做这样的事。所以问题是,使用箭头函数作为方法是say2或say3的方法是合理的。有更好的方法吗?

在ES6语法中,类的主体可能只由方法定义组成,因此这里不允许使用箭头函数表达式。这是语法相关部分的简化片段:

ClassBody :
    ClassElementList
ClassElementList :
    ClassElement
    ClassElementList ClassElement
ClassElement :
    MethodDefinition
    static MethodDefinition
    ;
MethodDefinition :
    PropertyName ( StrictFormalParameters ) { FunctionBody }
    GeneratorMethod
    get PropertyName ( ) { FunctionBody }
    set PropertyName ( PropertySetParameterList ) { FunctionBody }

所以在你的例子中:

class Person {
    constructor(aName) {
        this.name = aName;
        this.say2 = () => console.log(this.name);
    }
    say() { console.log(this.name) }
    say3() { () => console.log(this.name) }
}
  • say是一个正常的方法定义,它与正常函数一样存在this绑定的问题。但是,当您传递它时,您可以使用bind来绕过它,就像在element.addEventListener('click', this.say.bind(this));中一样
  • say2可以工作,但是您失去了在构造函数之外指定方法的便利性
  • say3不起作用——虽然它在语法上是有效的,但它将被解析为一个方法,其主体由一个箭头函数组成。为了澄清,say3() { () => console.log(this.name) }say3() { return () => console.log(this.name) }的不同之处在于,前者将不执行任何操作并返回undefined,而后者将返回一个箭头函数表达式,当调用该表达式时,该表达式将打印到控制台