Разберите JavaScript-кейс с this: const obj = { x: 1, getX() { return this.x; } }; const f = obj.getX; console.log(f()); Объясните, почему результат может быть undefined, как работают связывание контекста и способы исправления (bind, arrow-функции, вызов через obj.getX())

25 Фев в 09:39
16 +1
0
Ответы
1
Кейс и причина
- Код:
const obj = { x: 1, getX() { return this.x; } };
const f = obj.getX;
console.log(f());
- При вызове как `f()` функция теряет «неявную привязку» к `obj`. В non‑strict режиме `this` становится глобальным объектом (например `window`), у которого обычно нет свойства `x` → результат `undefined`. В strict режиме `this` будет `undefined`, и обращение `this.x` даст ошибку TypeError.
Итог: вызов может вернуть undefinedundefinedundefined (или бросить ошибку в strict).
Как работает связывание this (кратко, приоритет)
1. new‑binding — при вызове через `new` `this` — новый объект.
2. explicit — `call/apply/bind` задают `this` явно.
3. implicit — вызов через «владелец.метод()» связывает `this` с владельцем.
4. default — обычный вызов `fn()` → global (sloppy) или `undefined` (strict).
Способы исправления (с примерами)
1) Вызвать как метод (сохраняется implicit):
console.log(obj.getX()); // вернёт x (111)
2) bind (фиксирует контекст):
const f = obj.getX.bind(obj);
console.log(f()); // 111
3) call / apply (одноразово задать контекст):
console.log(obj.getX.call(obj)); // 111
4) Использовать стрелочную обёртку или замыкание (стрелка не имеет собственного this, берёт из окружения):
// вариант: замкнуть на самом obj
const f = () => obj.getX();
console.log(f()); // 111
// вариант: метод возвращает стрелку, которая захватит this метода (implicit сработал при вызове getX)
const obj2 = {
x: 1,
getX() { return () => this.x; }
};
const f2 = obj2.getX(); // при вызове getX() this = obj2
console.log(f2()); // 111
Важно про стрелочные методы в литерале объекта:
- Если написать getX: () => this.x, то стрелка захватит внешнее this (не `obj`) — это обычно не то, что нужно.
Рекомендация
- Если вы хотите, чтобы функция работала независимо от места вызова, используйте `bind` или явный замыкающий доступ через `obj`. Если метод должен видеть `this` как «владельца» — вызывать его как `obj.getX()`.
25 Фев в 09:47
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир