Методы в объектах ES6: использование функций стрелок

В ES6 оба из них являются законными:

var chopper = {
    owner: 'Zed',
    getOwner: function() { return this.owner; }
};

и, как стенография:

var chopper = {
    owner: 'Zed',
    getOwner() { return this.owner; }
}

Можно ли использовать новые функции стрелок? При попытке чего-то вроде

var chopper = {
    owner: 'John',
    getOwner: () => { return this.owner; }
};

или

var chopper = {
    owner: 'John',
    getOwner: () => (this.owner)
};

Я получаю сообщения об ошибках, предполагающие, что метод не имеет доступа к this. Это просто проблема синтаксиса, или вы не можете использовать методы толстой трубы внутри объектов ES6?

Ответы

Ответ 1

Функции стрелок не предназначены для использования в любой ситуации просто как более короткая версия старомодных функций. Они не предназначены для замены функционального синтаксиса с использованием ключевого слова function. Наиболее часто используемым случаем для функций стрелок является короткий "lambdas", который не переопределяет this, часто используется при передаче функции в качестве обратного вызова какой-либо функции.

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

// Whatever 'this' is here...
var chopper = {
    owner: 'Zed',
    getOwner: () => {
        return this.owner;    // ...is what 'this' is here.
    }
};

В вашем случае, желая написать метод для объекта, вы должны просто использовать традиционный синтаксис function или синтаксис метода, введенный в ES6:

var chopper = {
    owner: 'Zed',
    getOwner: function() {
        return this.owner;
    }
};

// or

var chopper = {
    owner: 'Zed',
    getOwner() {
        return this.owner;
    }
};

(Между ними существуют небольшие различия, но они важны только в том случае, если вы используете super в getOwner, которого вы не являетесь или копируете getOwner на другой объект.)

Существовал некоторые дебаты в списке рассылки ES6 о повороте на стрелки функций, которые имеют похожий синтаксис, но с их собственным this. Однако это предложение было плохо получено, потому что это простой синтаксический сахар, позволяющий людям печатать несколько символов и не предоставляет новых функциональных возможностей по сравнению с существующим синтаксисом функций. См. Раздел " Функции несвязанной стрелки".

Ответ 2

В этой строке getOwner: => (this.owner) должно быть:

var chopper = {
    owner: 'John',
    getOwner: () => this.owner
}; //here `this` refers to `window` object.

Вам нужно объявить this в функцию:

var chopper = {
    owner: 'John',
    getOwner() { return this.owner }
};

Или:

var chopperFn = function(){

    this.setOwner = (name) => this.owner = name;
    Object.assign(this,{
        owner: 'Jhon',
        getOwner: () => this.owner,
    })

}

var chopper = new chopperFn();
console.log(chopper.getOwner());
chopper.setOwner('Spiderman');
console.log(chopper.getOwner());

Ответ 3

Эта функция внутри стрелки не отражает контекст объекта. Вместо этого он дает контекст, в котором вызывается метод объекта.

Проверьте это. Это дает некоторое представление о том, когда использовать стрелку, а когда нет. https://dmitripavlutin.com/when-not-to-use-arrow-functions-in-javascript/

Ответ 4

Да, в объектном литерале можно использовать функции стрелок (с доступом к этому). Вы должны использовать метод Object.assign().

let chopper = {
    owner: 'John',
    getOwner: () => { console.log(this.owner); }
};

Object.assign(this, chopper);
chopper.getOwner();