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

Какая конструкция в JavaScript может сделать новый scope для this?

2.2 Middle🔥 281 комментариев
#JavaScript Core#Браузер и сетевые технологии

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

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

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

Конструкции JavaScript для создания нового Scope для this

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

Основные конструкции, создающие новый this

1. Методы объектов

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

const user = {
  name: 'Анна',
  greet() {
    console.log(`Привет, меня зовут ${this.name}`); // this = user
  }
};
user.greet(); // "Привет, меня зовут Анна"

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

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

function Person(name) {
  this.name = name; // this = новый объект
  this.sayHello = function() {
    console.log(${this.name}`);
  };
}
const anna = new Person('Анна');
anna.sayHello(); // "Я Анна"

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

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

  • .call() и .apply() вызывают функцию немедленно с заданным this.
  • .bind() создает новую функцию, которая навсегда привязывает this к указанному значению (и, возможно, части аргументов). .bind() — это мощная конструкция, которая по сути фабрика функций с новым, фиксированным контекстом.
function introduce(age, city) {
  console.log(`Меня зовут ${this.name}, мне ${age} лет, я из ${city}`);
}

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

// call - аргументы передаются списком
introduce.call(person, 30, 'Москвы'); // this = person

// apply - аргументы передаются массивом
introduce.apply(person, [30, 'Москвы']); // this = person

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

4. Стрелочные функции (Arrow Functions)

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

const team = {
  name: 'Разработчики',
  members: ['Анна', 'Борис', 'Виктор'],
  showMembers() {
    // Обычная функция внутри метода создала бы свой собственный this.
    // Стрелочная функция берет this из showMembers, т.е. из объекта team.
    this.members.forEach(member => {
      console.log(`${member} из команды "${this.name}"`);
    });
  }
};
team.showMembers(); // Корректно выводит имена с названием команды

5. Классы (ES6+)

Методы класса (как обычные, так и статические) имеют собственный контекст this, привязанный к экземпляру (или классу для статических методов). При вызове через new создается новый экземпляр, и this внутри конструктора ссылается на него.

class Car {
  constructor(model) {
    this.model = model; // this = новый экземпляр Car
  }

  drive() {
    console.log(`${this.model} едет!`); // this = экземпляр, на котором вызван метод
  }
}
const bmw = new Car('BMW');
bmw.drive(); // "BMW едет!"

Важные исключения и подводные камни

  • Прямой вызов функции (Function Invocation): При обычном вызове функции (не как метода) this будет либо undefined (в строгом режиме 'use strict'), либо ссылаться на глобальный объект (window в браузере) в нестрогом режиме. Это не создает новый полезный scope, а скорее приводит к потере контекста.
  • Глобальный контекст: В глобальной области видимости this ссылается на глобальный объект.

Итог и лучшие практики

  • Для создания нового, управляемого scope для this чаще всего используются: оператор new, методы объектов, и, что особенно важно, метод .bind(), который позволяет создать новую функцию с гарантированным контекстом.
  • Стрелочные функции — это инструмент для сохранения существующего лексического контекста, а не для создания нового.
  • В современном JavaScript для управления контекстом и избежания путаницы рекомендуется:
    1.  Использовать **стрелочные функции** для колбэков и вложенных функций.
    2.  Использовать **`.bind()`** в случаях, когда нужна отложенная функция с фиксированным контекстом.
    3.  Использовать **классы** и **методы** для четкой объектно-ориентированной структуры.
    4.  Избегать зависимости от глобального `this`, всегда работая в строгом режиме (`'use strict'`).

Таким образом, прямого аналога scope для переменных, но для this не существует. Контекст this определяется динамически в момент вызова функции, и перечисленные конструкции являются механизмами управления этим динамическим поведением.