В этом руководстве вы узнаете о метасвойствеnew.target
в JavaScript, которое определяет, была ли функция или конструктор вызваны с использованием оператора new
.
ES6 предоставляет метасвойство с именем new.target
, которое состоит из ключевого слова new
, точки и свойства target
. new.target
доступен во всех функциях.
Однако в стрелочных функциях new.targe
t принадлежит функции окружения.
new.target
очень полезен для проверки: выполняется ли функция как функция или как конструктор. Также удобно определить конкретный производный класс, который был вызван с помощью оператора new
из родительского класса.
Особенности
Давайте посмотрим на следующую функцию-конструктор Person
:
function Person(name) { this.name = name; }
Вы можете создать новый объект из функции Person
с помощью оператора new
следующим образом:
let john = new Person('John'); console.log(john.name); // john
Или вы можете вызвать Person
как функцию:
Person('Lily');
Поскольку this
устанавливается на глобальный объект, т. е. объект window
, когда вы запускаете JavaScript в веб-браузере, свойство name
добавляется к объекту window
следующим образом:
console.log(window.name); //Lily
Чтобы определить, была ли функция вызвана с помощью оператора new, используйте new.target
.
При обычном вызове функции new.target
возвращает значение undefined
. Если функция была вызвана с оператором new
, new.target
возвращает ссылку на функцию.
Предположим, вы не хотите, чтобы Person
вызывался как функция, вы можете использовать new.target
следующим образом:
function Person(name) { if (!new.target) { throw "must use new operator with Person"; } this.name = name; }
Теперь единственный способ использовать Person
— создать экземпляр объекта из него с помощью оператора new
. Если вы попытаетесь вызвать ее как обычную функцию, вы получите ошибку.
В конструкторах
В конструкторе класса new.target
ссылается на конструктор, который был вызван непосредственно оператором new
. true
, если конструктор находится в родительском классе и был делегирован конструктором дочернего класса:
class Person { constructor(name) { this.name = name; console.log(new.target.name); } } class Employee extends Person { constructor(name, title) { super(name); this.title = title; } } let john = new Person('John Doe'); // Person let lily = new Employee('Lily Bush', 'Programmer'); // Employee
В этом примере new.target.name
— это удобное для человека имя ссылки на конструктор new.target.
В этом руководстве вы узнали, как использовать метасвойство JavaScript new.target
, чтобы определить, была ли функция или конструктор вызваны с использованием оператора new
.