new 操作符的背后都做了什么?

347 阅读1分钟

new 操作符的作用

实例化出一个新的对象,并将新对象的原型对象指向当前构造函数的原型或者 Object.prototype

新对象的原型对象指向当前构造函数的原型

function Person(name, age) {
    this.name = name
    this.age = age
}

const p1 = new Person('Tom', 23)

运行结果

新对象的原型对象指向 Object.prototype

function Person(name, age) {
    this.name = name
    this.age = age

  return { name, age }
}

const p1 = new Person('Tom', 23)

运行结果

当返回值不是 Object 实例的时候自动忽略

function Person(name, age) {
    this.name = name
    this.age = age

  return 2
}

const p1 = new Person('Tom', 23)

运行结果

new 操作符的实现思路

  • 创建一个新的对象
  • 添加属性
  • 指定原型对象
  • 如果构造函数没有返回对象,就返回新建的对象
function myNew(target) {
    // 新建一个对象
    const obj = Object.create({})

    // 添加属性
    const result = target.apply(obj, Array.prototype.slice.call(arguments, 1))

    // 指定原型对象
    Object.setPrototypeOf(obj, target.prototype)
    // or
    // obj.__proto__ = target.prototype
    
    // 如果构造函数没有返回对象,就返回新建的对象
    return result instanceof Object ? result : obj
}

const p2 = myNew(Person, 'Skill', 23)

运行结果

为什么不使用 obj.proto = Object.create(target.prototype) 绑定原型对象

先看下使用 obj.proto = Object.create(target.prototype) 绑定原型对象的结果

function myNew(target) {
    // 新建一个对象
    const obj = Object.create({})

    // 添加属性
    const result = target.apply(obj, Array.prototype.slice.call(arguments, 1))

    // 指定原型对象
    obj.__proto__ = Object.create(target.prototype) 
    
    // 如果构造函数没有返回对象,就返回新建的对象
    return result instanceof Object ? result : obj
}

const p2 = myNew(Person, 'Skill', 23)

运行结果

多了一层的原因是因为 Object.create(target) 是基于目标对象(target)创建出一个实例

【笔记不易,如对您有帮助,请点赞,谢谢】