Skip to content

JavaScript new

实现原理

  1. 创建一个空的对象
    • 创建一个普通的对象 {}
    • 将新对象的 __proto__ 属性设置为构造函数的 prototype 属性,从而实现原型链继承
  2. 设置构造函数的上下文
    • 将构造函数的 this 绑定到新创建的对象
  3. 处理返回值
    • 如果构造函数显示返回了一个对象 return {...}, 则 new 操作的结果是这个返回的对象
    • 如果构造函数没有返回值,或者返回非对象的值(例如 return 42 或者 return undefined),则返回新创建的对象
  4. 返回新对象
    • 默认情况下,返回步骤 1 中创建并初始化的对象

这里可以联系 instanceof 来逆向推导

实现

示例代码

js
function myNew(constructor, ...args) {
  const obj = {}
  obj.__proto__ = constructor.prototype
  // const obj = Object.create(constructor.prototype)
  const result = constructor.apply(obj, args)
  return typeof result === 'object' && result !== null || typeof result === 'function' ? result : obj
}

测试代码

js
function Person(name, age) {
  this.name = name
  this.age = age
}
Person.prototype.say = function() {
  console.log(`Hello, my name is ${this.name}`)
}
// 原生的 new
const firstPerson = new Person('Alice', 18)
console.log(firstPerson)
firstPerson.say()

// 构造函数没有返回值
const secondPerson = myNew(Person, 'Jack', 19)
console.log(secondPerson)
secondPerson.say()

// 构造函数带返回值
function Car(model) {
  this.model = model
  return { custom: 'Custom Object' }
}
const firstCar = new Car('SU7')
console.log(firstCar)
const secondCar = myNew(Car, 'YU7')
console.log(secondCar)

拓展

  • 箭头函数没有自己的 thisprototype,因此不能使用 new