skip to content

JavaScript
new 的模拟实现

首先,我们先来看看 new 操作起了什么作用

// 构造函数 People (无显式返回值)
function People(name, age) {
  this.name = name
  this.age = age
}

People.prototype.printInfo = function () {
  return `My name is ${this.name} and ${this.age}`
}

// 构造函数 Student (有显式返回值,且返回值为对象类型)
function Student(name) {
  this.name = name
  return { ps: 'balabala' }
}

const p1 = new People('Jack', 17)
const s1 = new Student('David')
console.log(p1.name) // Jack
console.log(p1.age) // 17
console.log(p1.printInfo()) // My name is Jack and 17
console.log(s1) // {ps: "balabala"}

可以看出 new 关键字大体上有一下几个作用

  • 构造函数无显式返回值时(例如 Person),通过 new 操作得到的 p1 可以访问到构造函数 Person 里的属性和 Person.prototype 里的属性
  • 构造函数有显式返回值并且返回值为对象类型时(例如 Student),通过 new 操作得到的 s1 是构造函数的显示返回值 {ps: "balabala"}

基于以上的内容,我们来实现一个 new 操作

  1. 首先创建一个空对象,这个对象将会作为执行 new 构造函数() 之后,返回的对象实例
  2. 将上面创建的空对象的原型(__proto__),指向构造函数的 prototype 属性
  3. 将这个空对象赋值给构造函数内部的 this,并执行构造函数逻辑
  4. 根据构造函数执行逻辑,返回第一步创建的对象或者构造函数的显式返回值
const neo = (Con, ...args) => {
  const obj = Object.create(Con.prototype)
  const result = Con.apply(obj, args)
  return typeof result === 'object' ? result : obj
}

const p2 = neo(People, 'Jason', 18)
const s2 = neo(Student, 'Doug')
console.log(p2)
console.log(s2)

JavaScript 深入之 new 的模拟实现