Используйте стрелочные функции ECMAScript 6 в качестве методов класса

Я тестирую свой код с помощью узла v8.9.4

Я хочу использовать методы класса в своей цепочке обещаний. Но это не срабатывает с ошибкой: (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.info(this.attr);
    }

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

new MyClass().main();

Поэтому я стараюсь использовать стрелочные функции как методы класса. Но определение стрелочной функции как метода класса синтаксически неверно: Unexpected token =

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

Это работает, но действительно некрасиво:

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

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

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

new MyClass().main();

Итак, как я могу использовать методы класса в обещаниях?

По этой теме есть еще один вопрос: Как использовать стрелочные функции (поля открытого класса) в качестве методов класса? К сожалению, это не работает с моей установкой node.js.

Стрелочные функции как методы не получают правильной установки this при их вызове.

Pointy 23.12.2018 15:02
«Я хочу использовать методы класса в моей цепочке обещаний». -> somePromise.then(someClass.someMethod.bind(someClass)) для «метода класса» или somePromise.then(someInstance.someMethod.bind(someInstance)) для «метода экземпляра»
Mulan 23.12.2018 15:14

Обратите внимание, вы также можете использовать fsp.readdir('.').then(x => this.promiseMe(x))

Mulan 23.12.2018 15:18
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
141
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or 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

Вы получаете TypeError: Cannot read property 'attr' of undefined, потому что this не ссылается на ваш экземпляр класса.

Я понимаю эту проблему. Но как тогда я могу использовать свой метод класса в своих обещаниях?

Matthias M 23.12.2018 15:13

вы можете установить это в переменной и использовать эту переменную как это, например, let ref = this; перед стрелочной функцией

Prashant Pimpale 23.12.2018 15:14
Ответ принят как подходящий

Правильно, это потому, что ваш контекст неверен в вашем обещании. Один из способов - привязать this к контексту вашего обещания. В вашем примере вы бы назвали это как fsp.readdir('.').then(this.promiseMe.bind(this));

В качестве альтернативы, если вы используете это чаще, вы можете привязать его в своем конструкторе:

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

Это свяжет его в вашем классе, так что вам больше не нужно связывать каждый раз, когда вы вызываете!

Похоже, вы уже выяснили, какие у вас есть варианты синтаксиса class. Но я предлагаю вам спросить себя, действительно ли синтаксис / механизм class предоставляет то, что вам нужно.

Вполне возможно, что вы сможете выполнить все, что вам нужно, используя фабричную функцию. Это позволяет избежать всех уродливых причуд использования this:

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

function myClass() {
    let attr = 'value';

    const promiseMe = () => console.info(attr);
    const main = () => fsp.readdir('.').then(promiseMe);

    return { promiseMe, main };
}

myClass().main();

Другие вопросы по теме