跳到主要内容

new

2023年06月15日
柏拉文
越努力,越幸运

一、认识


二、语法


三、属性


3.1 new.target

ES6new命令引入了一个new.target属性,该属性一般用在构造函数之中,返回new命令作用于的那个构造函数。如果构造函数不是通过new命令或Reflect.construct()调用的,new.target会返回undefined,因此这个属性可以用来确定构造函数是怎么调用的。注意,在函数外部,使用new.target会报错。

语法

  • : 内部调用 new.target , 返回当前 ; 子类继承父类时,父类内部调用 new.target, 返回子类

    class Point {
    constructor() {
    console.log(new.target);
    }
    }

    const point = new Point(); // [class Point]
    class Point {
    constructor() {
    console.log(new.target);
    }
    }

    class ThreePoint extends Point {
    constructor() {
    super();
    console.log(new.target);
    }
    }

    const point = new Point(); // [class Point]
    const threePoint = new ThreePoint(); // [class ThreePoint extends Point] // [class ThreePoint extends Point]
  • 构造函数: 如果构造函数不是通过new命令或Reflect.construct()调用的,new.target会返回undefined

    function Point(name) {
    console.log(new.target);
    }

    Point(); // undefined

    const point = new Point(); // Point

四、场景


4.1 必须继承

方法一、通过 new.target

class Point {
constructor() {
if (new.target === Point) {
throw new Error('本类不能实例化');
}
}
}

class ThreePoint extends Point {
constructor() {
super();
}
}

// const point = new Point();
const threePoint = new ThreePoint();

4.2 必须 new

方法一、通过 instanceof

function Point() {
if (!(this instanceof Point)) {
console.log('必须通过 new 调用');
return;
}
console.log('new 调用之后');
}

Point(); // 必须通过 new 调用
const point = new Point(); // new 调用之后

方法二、通过 new.target

function Point() {
if (new.target !== Point) {
console.log('必须通过 new 调用');
return;
}
console.log('new 调用之后');
}

Point(); // 必须通过 new 调用
const point = new Point(); // new 调用之后

五、原理 Polyfill


  1. 创建一个空的简单JavaScript对象(即

  2. 为新创建的对象添加属性__proto__,将该属性链接至构造函数的原型对象prototype

  3. 将构造函数内部this绑定到新创建的对象 , 执行构造函数

  4. 如果构造函数没有显式返回一个对象,则返回新创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)

function myNew(constructor, ...argArray) {
const newObj = {};
Object.setPrototypeOf(newObj, constructor.prototype);
const result = constructor.call(newObj, ...argArray);
if (
(typeof result === "object" && result !== null) ||
typeof result === "function"
) {
return result;
} else {
return newObj;
}
}

function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.getName = function () {
return this.name;
};
const person = myNew(Person, "柏拉图", 23);
console.log(person);
console.log(person.getName());