JS Advanced

Конструктор и new

Разобрать, что делает оператор new: создаёт объект, привязывает this, устанавливает prototype, и возвращает результат.

Продвинутый (Advanced)

Кратко

new Constructor(args) выполняет 4 шага: 1) создаёт пустой объект, 2) устанавливает prototype = Constructor.prototype, 3) вызывает Constructor с this = новый объект, 4) возвращает объект (или результат constructor, если это объект).


Подробно

4 шага new:

function User(name) { this.name = name; } User.prototype.greet = function() { return Hi, ${this.name}; };

const user = new User('Анна');

// Что сделал new: // 1. const obj = {}; // 2. obj.__proto__ = User.prototype; // 3. User.call(obj, 'Анна'); → obj.name = 'Анна' // 4. return obj;

Проверка: console.log(user.name); // 'Анна' console.log(user.greet()); // 'Hi, Анна' console.log(user instanceof User); // true

Constructor может вернуть объект: function Fake() { this.real = true; return { fake: true }; // перезаписывает this! }

const f = new Fake(); console.log(f.fake); // true console.log(f.real); // undefined

Если constructor возвращает примитив — он игнорируется.

Проверка new (без new): function User(name) { if (!(this instanceof User)) { return new User(name); } this.name = name; }

// Можно вызвать без new: const user = User('Анна'); // тоже работает

Modern альтернатива: class // class всегда требует new // constructor возвращает объект — SyntaxError


Ментальная модель

new — как фабрика. Вы подаёте чертёж (Constructor) и материал (args). Фабрика: 1) берёт чистый лист (пустой объект), 2) ставит штамп завода (prototype), 3) заполняет по чертежу (this = obj), 4) отдаёт готовое изделие (объект).


Примеры

**Самый простой:**

javascript
function Car(brand) {
  this.brand = brand;
}
Car.prototype.drive = function() {
  return `${this.brand} is driving`;
};

const tesla = new Car('Tesla');
console.log(tesla.drive()); // 'Tesla is driving'
console.log(tesla instanceof Car); // true

Простейший конструктор с new.

**Простой:**

javascript
// Constructor, возвращающий объект
function Range(from, to) {
  this.from = from;
  this.to = to;
}

Range.prototype = {
  includes(x) {
    return x >= this.from && x <= this.to;
  },
  toString() {
    return `[${this.from}..${this.to}]`;
  }
};

const range = new Range(1, 10);
console.log(range.includes(5)); // true
console.log(`${range}`); // '[1..10]'

Конструктор + prototype для создания объектов.

**Реальный пример:**

javascript
// Паттерн: factory с проверкой new
function create(Constructor, ...args) {
  return new Constructor(...args);
}

// Или self-checking constructor
function MyClass(value) {
  if (!(new.target)) {
    throw new Error('Use new MyClass()');
  }
  this.value = value;
}

// new MyClass(42) — OK
// MyClass(42) — Error: Use new MyClass()

Паттерны: factory и self-checking constructor.


Частые ошибки

**Неправильно:** Забывать, что new может вернуть другой объект

**Почему:** Если constructor возвращает объект — new вернёт его, а не this.

**Правильно:** new возвращает: this (по умолчанию) или объект из constructor.

**Неправильно:** Думать, что new нужен только для class

**Почему:** new работает с любыми функциями-конструкторами.

**Правильно:** new Constructor() — вызов функции как конструктора.


Важно запомнить

  • new выполняет 4 шага: create, set prototype, call constructor, return
  • Constructor может вернуть объект (перезаписывает this)
  • Constructor.prototype becomes [[Prototype]]
  • instanceof проверяет prototype chain
  • class всегда требует new

Связь

Назад: Вы знаете классы (JI8) и прототипы (JV6). Этот урок объясняет механизм, стоящий за new.

Вперёд: Следующий урок (JV13) — расширение встроенных классов, например Array.

Материалы курса JS Advanced — PROlab Academy.