实现 new

167 阅读1分钟

new做了什么

mdn对new关键字有这样的描述

  1. 创建一个空的、普通的对象
  2. 为刚刚创建的对象添加一个链接到构造函数的原型对象的属性(即__proto__)
  3. 将刚刚创建的对象作为this上下文
  4. 如果构造函数返回了一个对象则返回该对象,否则返回刚刚创建的对象

实现

根据第1、2步,很自然想到如下代码。

function myNew(Construtor){
    const obj = {};
    obj.__proto__ = Construtor.prototype;
}

其实Object.create()可以完成这两件事,该函数的作用就是创建对象并使用指定的对象作为该对象的原型对象。

function myNew(Construtor){
    const obj = Object.create(Construtor.prototype);
}

第3、4步的意思是调用构造函数并绑定this,然后检查其返回值。最终代码如下

function myNew(Construtor){
    //创建空对象
    const obj = Object.create(Construtor.prototype);
    return function(){
        //绑定this
        const ret = Construtor.apply(obj,arguments);
        //优先返回构成函数返回的对象
        return ret instanceof Object ? ret : obj;
    }
}

测试

function myNew(Construtor){
    const obj = Object.create(Construtor.prototype);
    return function(){
        const ret = Construtor.apply(obj,arguments);
        return ret instanceof Object ? ret : obj;
    }
}

function Foo(a,b){
    this.a =a;
    this.b=b;
}
const foo = myNew(Foo)(1,2);
console.log(foo) // Foo {a: 1, b: 2}
console.log(foo instanceof Foo) //true