Какова роль ключевого слова new в Javascript? Как работает new при вызове функции? Что происходит, когда мы вызываем функцию без ключевого слова new? Это лишь некоторые из уместных вопросов, которые разработчик может задать на пути к пониманию объектно-ориентированного программирования в контексте Javascript. В этой статье я попытаюсь ответить на эти вопросы и дать больше ясности относительно использования нового ключевого слова в Javascript.

Во-первых, зачем вообще использовать ключевое слово new? Какую дополнительную функциональность мы получаем по сравнению с фабриками объектов?

Обратите внимание на этот пример кода:

В строках 18 и 19 мы проверяем, ссылаются ли свойства конструктора accord и corolla на их прототипах на функции, создавшие их. Мы наблюдаем, что с фабрикой объектов вместо createCar в качестве конструктора регистрируется Object Function. С другой стороны, используя конструктор с ключевым словом new, мы видим, что свойство constructor для объекта corolla правильно ссылается на функцию, которая создала объект, которым является CreateCar.

Кроме того, мы можем проверить это с помощью оператора instanceof в строках 21 и 22. Оператор instanceof проверяет, появляется ли свойство prototype конструктора. в цепочке прототипов объекта. Мы видим, что accord не является экземпляром createCar, поскольку свойство прототипа конструктора не появляется в цепочке прототипов accord. Мы наблюдаем обратное с объектом corolla, поскольку свойство прототипа конструктора CreateCar появляется в цепочке прототипов corolla. сильный>.

Следовательно, мы видим преимущество использования конструкторов с ключевым словом new: функции конструктора позволяют разработчикам определять тип создаваемого объекта.

Как же тогда мы можем проявить эту способность определять тип созданного объекта? Ответ заключается в ключевом слове new.

роль ключевого слова new заключается в выполнении следующих операций:

  1. Он создает совершенно новый объект.
  2. Он устанавливает прототип нового объекта в объект, на который ссылается свойство конструктора prototype.
  3. Он устанавливает значение this для использования внутри функции, чтобы указать на новый объект.
  4. Он вызывает функцию. Поскольку this относится к новому объекту, мы используем его внутри функции для установки свойств и методов объекта.
  5. Наконец, когда функция завершает работу, new возвращает новый объект, даже если мы ничего не возвращали явно.

В предыдущем примере кода мы вызвали функцию CreateCar с ключевым словом new в строке 16 (4), был создан новый объект (1) и прототип был задан прототип конструктора (2).

Вторую операцию можно подтвердить следующим примером кода:

В строке 11 мы проверяем, ссылается ли прототип вновь созданного объекта на прототип функции CreateCar, которая регистрирует значение true, подтверждая (2 ).

Ключевое слово new также устанавливает значение this для ссылки на вновь созданный объект, что позволяет нам добавлять методы и свойства к указанному объекту (3).

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

Что произойдет, если мы укажем явный возврат?

Давайте посмотрим на другой пример кода:

Когда мы пытаемся явно вернуть примитивное значение функции CreateCar в строке 6, мы по-прежнему возвращаем вновь созданный объект, созданный с помощью ключевого слова new, о чем свидетельствует строка 10. Однако когда мы явно возвращаем объект, ключевое слово new кажется отрицательным, и указанный нами объект возвращается, о чем свидетельствует явный возврат в строках 16–19 и вывод значений corollaExplicitReturn объект в строке 23.

Таким образом, принцип заключается в том, что конструктор, который явно возвращает объект, возвращает этот объект вместо вновь созданного объекта с помощью нового ключевого слова. Если возвращаемое значение не является объектом, вместо него возвращается вновь созданный объект с помощью new.

Из-за такого неожиданного поведения следует помнить, что явное возвращение объекта внутри функции-конструктора с ключевым словом new превращает его в фабрику объектов.

Мы можем наблюдать такое поведение на следующем примере кода:

Конструктор явно возвращаемого объекта не ссылается на функцию-конструктор, которая использовалась для создания этого объекта, вместо этого превращая наш конструктор в фабрику объектов.