在本教程中,您将了解 JavaScript  元属性 new.targetnew.target 属性检测是否使用 new 关键词调用函数或构造函数。

JavaScript new.target 简介

ES6 提供元属性 new.target,它允许您检测是否使用 new 运算符调用函数或构造函数。

new.target 由关键词 new、点和 target 属性组成。new.target 在所有函数中都可用。

但是,在箭头函数中, new.target 是属于周围函数的那个​​。

new.target 对于在运行时检查函数是作为函数还是作为构造函数执行非常有用。也可以确定从父类使用 new 运算符调用的特定派生类也很方便。。

JavaScript 函数的  new.target

让我们看看下面的 Person 构造函数:

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

您可以使用 new 运算符从函数创建 Person 对象,如下所示:

let john = new Person('John');
console.log(john.name); // john

或者您可以将 Person 作为函数调用 :

Person('Lily');

因为 this 被设置为全局对象,也就是您在 Web 浏览器运行 JavaScript 时的 window 对象,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;
}

现在,唯一的使用方法是使用 new 运算符从 Person 实例化一个对象。如果您尝试将其作为常规函数调用,则会出现错误。

JavaScript 构造函数的  new.target

在类构造函数中,new.target 指的是被 new 运算符直接调用的构造函数。 如果构造函数在父类中并且是从子类的构造函数委托的,new.target 则为 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 运算符调用函数或构造函数。