Методы в объектах 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?
4 ответа
Функции стрелок не предназначены для использования в любой ситуации просто как укороченная версия старомодных функций. Они не предназначены для замены синтаксиса функции с помощью function
ключевое слово. Наиболее распространенный вариант использования функций стрелок - это короткие "лямбды", которые не переопределяют 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
, Тем не менее, это предложение было получено плохо, потому что это просто синтаксический сахар, позволяющий людям экономить на наборе нескольких символов и не обеспечивающий никаких новых функциональных возможностей по сравнению с существующим синтаксисом функции. Смотрите тему несвязанных стрелок функций.
В этой строке 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());
Если вам нужно использовать функцию стрелки, вы можете изменить this
к chopper
,
var chopper = {
owner: "John",
getOwner: () => chopper.owner
};
Хотя это не лучшая практика, при изменении имени объекта необходимо изменить эту стрелочную функцию.
Небольшой совет, которому я следую, чтобы использовать функции стрелок.
- Используйте функции без стрелок для методов, которые будут использовать
object.method()
синтаксис. (Это функции, которые получат значимыеthis
значение от их вызывающего.) - Используйте функцию стрелки почти для всего остального.
Еще один совет, в строгом режиме
this
по-прежнему относится к Window вместо undefined.
(() => {
"use strict";
console.log(this); // window
})();
(function () {
"use strict";
console.log(this); // undefined
})();
Эта внутренняя функция стрелки не отражает контекст объекта. Вместо этого он дает контекст, где вызывается метод объекта.
Проверьте это, это дает некоторое представление о том, когда использовать стрелку, а когда нет. https://dmitripavlutin.com/when-not-to-use-arrow-functions-in-javascript/
Да, можно использовать функции стрелки (с доступом к этому) в литерале объекта. Вы должны использовать метод Object.assign().
let chopper = {
owner: 'John',
getOwner: () => { console.log(this.owner); }
};
Object.assign(this, chopper);
chopper.getOwner();