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

Откуда берется контекст

1.8 Middle🔥 161 комментариев
#React#State Management

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

Откуда берется контекст в JavaScript

Контекст (значение this) — одна из самых сложных концепций в JavaScript. Это переменная, которая указывает на объект, в контексте которого выполняется функция. Откуда берется контекст, зависит от способа вызова функции.

Правила определения контекста

Контекст определяется в момент вызова функции, а не в момент её определения:

const user = {
  name: "Алиса",
  greet: function() {
    console.log("Привет, " + this.name);
  }
};

user.greet(); // Привет, Алиса — здесь this = user
const greetFn = user.greet;
greetFn(); // Привет, undefined — здесь this = window или undefined (strict mode)

Способы вызова функций

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

Если функция вызывается как метод объекта, то this указывает на этот объект:

const obj = {
  value: 42,
  getValue: function() {
    return this.value;
  }
};

obj.getValue(); // 42 — this = obj

2. Обычный вызов функции

В обычном вызове (не как метод) this указывает на глобальный объект (в браузере — window, в Node.js — global), или undefined в strict mode:

function getThis() {
  return this;
}

getThis(); // window (в браузере) или global (в Node.js)

function getThisStrict() {
  "use strict";
  return this;
}

getThisStrict(); // undefined

3. Вызов через call(), apply(), bind()

Эти методы явно устанавливают контекст:

function introduce(greeting) {
  console.log(greeting + ", " + this.name);
}

const alice = { name: "Алиса" };
const bob = { name: "Боб" };

introduce.call(alice, "Привет"); // Привет, Алиса
introduce.apply(bob, ["Привет"]); // Привет, Боб

const boundIntroduce = introduce.bind(alice);
boundIntroduce("Привет"); // Привет, Алиса

4. Конструктор (оператор new)

При вызове с new контекст указывает на новый объект:

function Person(name) {
  this.name = name;
}

const person = new Person("Чарли");
console.log(person.name); // Чарли — this = person

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

Стрелочные функции не имеют своего контекста. Они наследуют this из лексического окружения (из места определения, а не вызова):

const obj = {
  name: "Дэвид",
  greet: function() {
    const arrow = () => {
      console.log(this.name);
    };
    arrow();
  }
};

obj.greet(); // Дэвид — стрелка наследует this от метода

const obj2 = {
  name: "Ева",
  greet: () => {
    console.log(this.name); // undefined — стрелка наследует this из глобального объекта
  }
};

Порядок приоритета

Если несколько правил применяются одновременно, приоритет такой:

  1. new — контекст = новый объект
  2. call()/apply()/bind() — явно переданный контекст
  3. Метод объекта — контекст = объект слева от точки
  4. Стрелочная функция — контекст наследуется
  5. Обычный вызов — контекст = глобальный объект (или undefined в strict mode)

Практический пример

const logger = {
  name: "Logger",
  log: function(message) {
    console.log(this.name + ": " + message);
  }
};

logger.log("привет"); // Logger: привет

const logFn = logger.log;
logFn("привет"); // undefined: привет (в strict mode — ошибка)

const boundLog = logger.log.bind(logger);
boundLog("привет"); // Logger: привет

Заключение

Контекст в JavaScript — это динамическое свойство, определяемое способом вызова функции. Понимание этого механизма критично для работы с методами, колбэками и событиями в браузере.