new之后发生了什么?

265 阅读1分钟

new之后发生了什么

数实例对象

  • 以下是常见的通过构造函数实例化对象的方式
// 声明构造函数
function Person(name) {
  this.name = name  // 实例的属性
}
// 声明实例的方法
Person.prototype.sayHi = function () {
  console.log('你好,' + this.name)
}
// 实例对象
let obj = new Person('张三')
obj.sayHi()     //  你好,张三
console.log(obj)  // Person {name: '张三'}

从以上代码中可以看出:

  1. 从实例对象obj的值来看,new之后返回了一个对象
  2. 从实例对象obj的属性name来看,new之后会调用构造函数,并改变调用的this为obj
  3. 从sayHi方法看,返回的这个对象的__proto__等于构造函数的prototype
  4. __prop__中的constructor属性指向构造函数本身

由此可以推断出new的过程:

  1. 创建一个新对象
  2. 将该对象的原型指向构造函数的原型
  3. 执行构造函数中的代码,this指向这个新对象(为这个新对象添加属性)
  4. 返回该对象

手写实现一个new函数

  • 根据实例化的过程,手写实现一个new函数
// 创建new函数
function myNew(fn, ...arg) {
  // 创建一个对象,并让其原型等于构造函数的原型
  const target = Object.create(fn.prototype)
  // 执行构造函数,this指向target
  fn.apply(target, arg)
  // 返回该对象
  return target
}

// 测试代码
// 创建构造函数
function Person(name) {
  this.name = name
}
Person.prototype.sayHi = function () {
  console.log('你好,' + this.name)
}
// 实例化
let obj = myNew(Person, '张三')
console.log(obj)   // Person {name: '张三'}
obj.sayHi()       //  你好,张三
console.log(obj instanceof Person)  // true