简体   繁体   English

使用ECMAScript 6箭头函数作为类方法

[英]Use ECMAScript 6 arrow functions as class methods

I'm testing my code with node v8.9.4 我正在用节点v8.9.4测试我的代码

I want to use class methods in my promises chain. 我想在我的Promise链中使用类方法。 But this fails with an error: (node:68487) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property 'attr' of undefined 但这失败并出现错误: (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();

So I try to use arrow functions as class methods. 因此,我尝试将箭头函数用作类方法。 But defining an arrow function as a class method is syntactically not correct: Unexpected token = 但是将箭头函数定义为类方法在语法上是不正确的: Unexpected token =

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

This works, but it is really ugly: 这可行,但确实很丑陋:

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

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

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

new MyClass().main();

So how can I use class methods in promises? 那么如何在promise中使用类方法呢?

There is another question regarding this topic: How to use arrow functions (public class fields) as class methods? 关于此主题还有另一个问题: 如何将箭头函数(公共类字段)用作类方法? Unfortunately this doesn't work with my node.js setup. 不幸的是,这不适用于我的node.js设置。

Right this is because your context is incorrect within your Promise. 正确,这是因为您在Promise中的上下文不正确。 One method is to bind this to your Promise context. 一种方法是this绑定到您的Promise上下文。 In your example you would call it like fsp.readdir('.').then(this.promiseMe.bind(this)); 在您的示例中,您将其fsp.readdir('.').then(this.promiseMe.bind(this));

Alternatively, if you're using this more often, you can bind it in your constructor: 另外,如果您更频繁地使用它,则可以将其绑定到构造函数中:

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

This will bind it in your class so that you no longer need to bind every time you call! 这会将它绑定到您的类中,这样您就不再需要在每次调用时都进行绑定!

An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target. 箭头函数表达式的语法比函数表达式短,并且没有自己的this,arguments,super或new.target。 These function expressions are best suited for non-method functions, and they cannot be used as constructors. 这些函数表达式最适合于非方法函数,因此不能用作构造函数。

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

You are getting TypeError: Cannot read property 'attr' of undefined because this is not referencing your class instance. 您将收到TypeError: Cannot read property 'attr' of undefined因为this没有引用您的类实例。

It looks like you've already figured out what options you have when it comes to the class syntax. 看来您已经弄清楚了有关class语法的选择。 But I suggest that you ask yourself the whether the class syntax/mechanism is actually providing something you need. 但是我建议您自问class语法/机制是否确实在提供您所需要的东西。

It may well be the case that you can accomplish everything you need by using a factory function. 您很可能可以通过使用工厂功能来完成所需的一切。 This avoids all the ugly quirks of using this : 这避免了使用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();

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

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