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

Какой контекст у функции созданной через new?

1.8 Middle🔥 291 комментариев
#JavaScript Core

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

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

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

Контекст функции, созданной через new

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

Механизм работы оператора new

При вызове new MyFunction() JavaScript выполняет четыре шага:

  1. Создание нового пустого объекта, который наследует от MyFunction.prototype.
  2. Привязка this внутри функции MyFunction к этому новому объекту.
  3. Выполнение кода функции MyFunction (обычно она модифицирует this, добавляя свойства).
  4. Возврат этого нового объекта (если функция не возвращает свой собственный объект явно).
function Car(model) {
  // На этом этапе 'this' уже ссылается на новый объект
  this.model = model;
  this.speed = 0;
  // Неявно возвращается 'this' (новый объект)
}

const myCar = new Car('Tesla');
console.log(myCar.model); // 'Tesla'
console.log(myCar.speed); // 0

Детали контекста и возвращаемого значения

Ключевой момент: контекст (this) внутри функции-конструктора — это новый экземпляр. Однако, если функция, вызванная через new, явно возвращает объект, то будет возвращён он, а не автоматически созданный this.

function A() {
  this.value = 10;
  return { custom: 999 }; // Явный возврат объекта
}
function B() {
  this.value = 10;
  return 42; // Явный возврат примитива игнорируется
}

const a = new A();
console.log(a); // { custom: 999 }, а не { value: 10 }
console.log(a.value); // undefined

const b = new B();
console.log(b); // { value: 10 } (примитив 42 проигнорирован)

Сравнение с обычным вызовом функции

Без new контекст функции определяется стандартными правилами (глобальный объект, undefined в строгом режиме, контекст объекта при вызове метода и т.д.).

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

// Вызов без 'new' — опасная ошибка!
const oops = Person('Alice');
console.log(oops); // undefined
console.log(globalThis.name); // 'Alice' (в браузере: window.name) — свойство создалось на глобальном объекте!

Современные альтернативы и лучшие практики

Хотя механизм new и конструкторов исторически важен, в современном JavaScript чаще используются:

  • Классы (ES2015+) — синтаксический сахар над функциями-конструкторами, который делает намерения более явными и безопасными (вызов без new приведёт к ошибке).

    class Animal {
      constructor(type) {
        this.type = type; // 'this' — экземпляр класса
      }
    }
    const cat = new Animal('Cat');
    
  • Object.create() для явного создания объектов с заданным прототипом.

Для надёжности функции, предназначенные для вызова с new, часто начинают с заглавной буквы (ConstructorFunction). Внутри них можно добавить проверку, была ли функция вызвана корректно:

function SafeConstructor(value) {
  // Защита от вызова без 'new'
  if (!(this instanceof SafeConstructor)) {
    return new SafeConstructor(value);
  }
  this.value = value;
}

const obj1 = new SafeConstructor(1); // Работает
const obj2 = SafeConstructor(2);     // Тоже работает, т.к. проверка внутри создаст экземпляр

Итог

Контекст функции, вызванной через new, — это вновь созданный объект-экземпляр, который неявно возвращается из функции (если она не возвращает другой объект явно). Этот механизм лежит в основе классической модели наследования в JavaScript, хотя сегодня для этих целей рекомендуется использовать более понятный и безопасный синтаксис классов. Понимание работы new критически важно для отладки, чтения legacy-кода и глубокого понимания языка.

Какой контекст у функции созданной через new? | PrepBro