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: '张三'}
从以上代码中可以看出:
- 从实例对象obj的值来看,new之后返回了一个对象
- 从实例对象obj的属性name来看,new之后会调用构造函数,并改变调用的this为obj
- 从sayHi方法看,返回的这个对象的__proto__等于构造函数的prototype
- __prop__中的constructor属性指向构造函数本身
由此可以推断出new的过程:
- 创建一个新对象
- 将该对象的原型指向构造函数的原型
- 执行构造函数中的代码,this指向这个新对象(为这个新对象添加属性)
- 返回该对象
手写实现一个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