Дан фрагмент JavaScript: const obj = {a:1, getA: () => this.a}; console.log(obj.getA()); Объясните результат, роль лексического this в стрелочных функциях и как исправить, если нужно доступаться к obj.a
Результат: в большинстве окружений код выведет `undefined`. Причина — стрелочная функция не имеет собственного `this`, она лексически захватывает `this` из внешней области, где она создана (обычно глобальный/модульный контекст), а не из объекта `obj`. В вашем примере `this.a` внутри стрелки не равен `obj.a`, поэтому получается `undefined` (если в глобальной области `a` не определено). Почему так: стрелочные функции используют лексическое `this` — это значение `this` берётся во время определения функции, и его нельзя изменить вызовом, `.call/.apply` или `.bind`. Как исправить (варианты): 1) Сделать метод обычной функцией (вызов `obj.getA()` установит `this === obj`): const obj = { a: 111, getA: function() { return this.a } }; console.log(obj.getA()); // -> 111 или синтаксис-метод: const obj = { a: 111, getA() { return this.a } }; 2) Если нужен замыкание на сам объект, вернуть напрямую `obj.a` (стрелка здесь будет работать, но метод перестаёт быть «динамическим»): const obj = { a: 111, getA: () => obj.a }; 3) Можно использовать `.bind` только для обычной функции, не для стрелочной (для стрелочной `.bind` не изменит `this`). Коротко: используйте обычную функцию (или метод shorthand), если хотите, чтобы `this` ссылался на объект-вызыватель.
Почему так: стрелочные функции используют лексическое `this` — это значение `this` берётся во время определения функции, и его нельзя изменить вызовом, `.call/.apply` или `.bind`.
Как исправить (варианты):
1) Сделать метод обычной функцией (вызов `obj.getA()` установит `this === obj`):
const obj = { a: 111, getA: function() { return this.a } };
console.log(obj.getA()); // -> 111
или синтаксис-метод:
const obj = { a: 111, getA() { return this.a } };
2) Если нужен замыкание на сам объект, вернуть напрямую `obj.a` (стрелка здесь будет работать, но метод перестаёт быть «динамическим»):
const obj = { a: 111, getA: () => obj.a };
3) Можно использовать `.bind` только для обычной функции, не для стрелочной (для стрелочной `.bind` не изменит `this`).
Коротко: используйте обычную функцию (или метод shorthand), если хотите, чтобы `this` ссылался на объект-вызыватель.