在 ES6 中,函数有两个不同的内部方法:[[call]][[Construct]] 。当通过 new 关键字调用函数时,执行的是 [[Construct]] 函数,它负责创建一个通常被称作实例的新对象。如果不通过 new 关键字调用函数,则执行 [[call]] 函数,从而直接执行代码中的函数体。

    当调用函数的 [[Construct]] 方法时,new.target 被赋值为 new 操作符的目标,通常是新创建对象实例的构造函数。

    1. function Person(name) {
    2. console.log('typeof new.target:', typeof new.target);
    3. console.log('new.target:', new.target);
    4. if (typeof new.target !== 'undefined') {
    5. this.name = name;
    6. } else {
    7. throw new Error('必须通过 new 关键字来调用 Person');
    8. }
    9. }
    10. const person = new Person();

    执行结果:

    1. typeof new.target: function
    2. new.target: function Person(name) {
    3. console.log('typeof new.target:', typeof new.target);
    4. console.log('new.target:', new.target);
    5. if (typeof new.target !== 'undefined') {
    6. this.name = name;
    7. } else {
    8. throw new Error('必须通过 new 关键字来调用 Person');
    9. }
    10. }

    如果调用函数的 [[call]] 方法,则 new.target 的值为 undefined

    1. function Person(name) {
    2. console.log('new.target:', new.target);
    3. }
    4. const person = Person();

    执行结果:

    1. new.target: undefined