← Назад к вопросам

От чего зависит this в функции?

2.0 Middle🔥 241 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

От чего зависит this в функции в JavaScript?

Значение this в JavaScript — одна из самых запутанных тем для начинающих. В отличие от многих других языков, где this (или self) всегда ссылается на текущий экземпляр объекта, в JavaScript this является динамическим и определяется в момент вызова функции, а не в момент её объявления. Его значение зависит от контекста вызова.

Основные правила определения this

1. Вызов в глобальном контексте или простой функции

При вызове обычной функции (не метода объекта) в нестрогом режиме this ссылается на глобальный объект (window в браузере, global в Node.js). В строгом режиме ('use strict') this будет undefined.

function showThis() {
    console.log(this);
}

showThis(); // В браузере: Window {...} (нестрогий режим) или undefined (строгий режим)

2. Вызов как метода объекта

Если функция вызывается как метод объекта, this ссылается на объект, которому принадлежит метод.

const user = {
    name: 'Анна',
    greet() {
        console.log(`Привет, ${this.name}!`);
    }
};

user.greet(); // this = user, вывод: "Привет, Анна!"

3. Явная привязка с помощью call(), apply() и bind()

Эти методы позволяют явно указать значение this.

  • call(context, arg1, arg2...) и apply(context, [arg1, arg2...]) вызывают функцию с заданным this и аргументами.
  • bind(context) создаёт новую функцию с навсегда привязанным значением this.
function introduce(age) {
    console.log(`Меня зовут ${this.name}, мне ${age} лет.`);
}

const person = { name: 'Иван' };

// call и apply вызывают функцию сразу
introduce.call(person, 30);    // this = person
introduce.apply(person, [30]); // this = person

// bind создаёт новую функцию с привязанным контекстом
const boundIntroduce = introduce.bind(person);
boundIntroduce(30); // this всегда = person

4. Вызов в конструкторе (с оператором new)

При вызове функции с оператором new, this ссылается на вновь созданный пустой объект, который затем возвращается конструктором.

function Car(model) {
    this.model = model; // this = новый пустой объект
    // Неявно возвращается this
}

const myCar = new Car('Toyota');
console.log(myCar.model); // 'Toyota'

5. Стрелочные функции (=>)

Стрелочные функции НЕ имеют своего this. Они захватывают значение this из окружающего лексического контекста (т.е. берут this там, где были объявлены). Это делает их очень удобными для использования внутри колбэков, где нужно сохранить контекст.

const obj = {
    value: 42,
    regularFunc: function() {
        setTimeout(function() {
            console.log(this.value); // undefined! this = Window/undefined (правила п.1)
        }, 100);
    },
    arrowFunc: function() {
        setTimeout(() => {
            console.log(this.value); // 42! this взят из arrowFunc (где this = obj)
        }, 100);
    }
};

obj.regularFunc(); // undefined
obj.arrowFunc();   // 42

6. Обработчики событий в DOM

При назначении функции как обработчика события через onclick или addEventListener, this внутри этой функции ссылается на DOM-элемент, который вызвал событие (если только не использована стрелочная функция или bind).

button.addEventListener('click', function() {
    console.log(this); // HTMLButtonElement
});

Итог: приоритет правил

Значение this определяется в следующем порядке приоритета (от высшего к низшему):

  1. newthis = новый объект.
  2. Явная привязка (call, apply, bind) – this = указанный объект.
  3. Вызов как метода (obj.method()) – this = объект перед точкой.
  4. Простой вызов или глобальный контекстthis = undefined (строгий режим) или глобальный объект.
  5. Стрелочные функцииthis берётся из внешнего лексического окружения (правила выше не применяются).

Понимание этих правил позволяет полностью контролировать контекст выполнения и избегать классических ошибок, таких как потеря this в асинхронных колбэках. Рекомендуется для явного управления контекстом активно использовать bind и стрелочные функции, а также соблюдать строгий режим ('use strict') для более предсказуемого поведения.