实现 new 关键字

96 阅读1分钟

实现 new

new关键字到底做了什么事情?

  1. 首先创建一个空对象,这个对象将会作为执行构造函数之后返回的对象实例
  2. 使上面创建的空对象的原型(__proto__)指向构造函数的prototype
  3. 将这个空对象赋值给构造函数内部的this,并执行构造函数逻辑
  4. 根据构造函数执行逻辑,返回第一步创建的对象或构造函数的显示返回值
function Person(name){
    this.name = name
}

const person = new newFunc(Person, 'lucas')

console.log(person) //{name: 'lucas'}

根据预期使用方式,我们可以实现newFunc,代码如下

function newFunc(...args){
    const constructor = args.shift()
    
    //创建一个空对象,且使这个空对象继承构造函数的prototype属性
    //既实现 obj.__proto__ === constructor.prototype
    const obj = Object.create(constructor.prototype)
    
    const result = constructor.apply(obj, args)
    
    return (typeof result === 'object' && result != null) ? result : obj
}

关键点如下

  1. 使用Object.create使obj的__proto__指向构造函数的原型
  2. 使用apply方法使构造函数内的this指向obj
  3. 构造函数如果有显示返回值,且返回值为对象类型,那么构造函数返回结果就不再是目标实例
    function Person(name){
        this.name = name
        return {1: 1}
    }
    
    const person = new newFunc(Person, 'lucas')
    
    console.log(person) //{1: 1}