【问题标题】:Use ECMAScript 6 arrow functions as class methods使用 ECMAScript 6 箭头函数作为类方法
【发布时间】:2018-12-23 14:00:11
【问题描述】:

我正在使用 node v8.9.4 测试我的代码

我想在我的 Promise 链中使用类方法。但这失败并出现错误: (node:68487) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property 'attr' of undefined

const fsp = require('fs-promise');

class MyClass {
    constructor() {
        this.attr = 'value';
    }

    promiseMe() {
        console.log(this.attr);
    }

    main() {
        fsp.readdir('.').then(this.promiseMe);
    }
}

new MyClass().main();

所以我尝试使用箭头函数作为类方法。 但是将箭头函数定义为类方法在语法上是不正确的: Unexpected token =

promiseMe = () =>  {
    console.log(this.attr);
}

这行得通,但它真的很难看:

const fsp = require('fs-promise');

class MyClass {
    constructor() {
        this.attr = 'value';
        this.promiseMe = () => {console.log(this.attr);}
    }

    main() {
        this.promiseMe();
    }
}

new MyClass().main();

那么如何在 Promise 中使用类方法呢?

关于这个话题还有一个问题: How to use arrow functions (public class fields) as class methods? 不幸的是,这不适用于我的 node.js 设置。

【问题讨论】:

  • 箭头函数作为方法在被调用时不会正确设置this
  • “我想在我的 Promise 链中使用类方法。” -> somePromise.then(someClass.someMethod.bind(someClass)) 用于“类方法”或somePromise.then(someInstance.someMethod.bind(someInstance)) 用于“实例方法”
  • 注意你也可以使用fsp.readdir('.').then(x => this.promiseMe(x))

标签: javascript ecmascript-6 arrow-functions


【解决方案1】:

是的,这是因为您的上下文在您的 Promise 中不正确。一种方法是将 this 绑定到您的 Promise 上下文。在您的示例中,您可以将其称为 fsp.readdir('.').then(this.promiseMe.bind(this));

或者,如果您更频繁地使用它,您可以在构造函数中绑定它:

this.promiseMe = this.promiseMe.bind(this)

这会将它绑定到你的类中,这样你就不再需要每次调用时都绑定了!

【讨论】:

    【解决方案2】:

    看起来您已经弄清楚在class 语法方面有哪些选项。但我建议你问问自己class 语法/机制是否真的提供了你需要的东西。

    您很可能可以通过使用工厂函数来完成所需的一切。这避免了使用this 的所有丑陋怪癖:

    const fsp = require('fs-promise');
    
    function myClass() {
        let attr = 'value';
    
        const promiseMe = () => console.log(attr);
        const main = () => fsp.readdir('.').then(promiseMe);
    
        return { promiseMe, main };
    }
    
    myClass().main();
    

    【讨论】:

      【解决方案3】:

      箭头函数表达式的语法比函数短 表达式并且没有自己的 this、arguments、super 或 新目标。这些函数表达式最适合非方法 函数,它们不能用作构造函数。

      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

      您收到 TypeError: Cannot read property 'attr' of undefined 是因为 this 没有引用您的类实例。

      【讨论】:

      • 我理解这个问题。但是我怎么能在我的承诺中使用我的类方法呢?
      • 你可以在一个变量中设置 this 并在箭头函数之前使用该变量作为 this 像 let ref = this;
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      相关资源
      最近更新 更多