JavaScript new
实现原理
- 创建一个空的对象
- 创建一个普通的对象
{} - 将新对象的
__proto__属性设置为构造函数的prototype属性,从而实现原型链继承
- 创建一个普通的对象
- 设置构造函数的上下文
- 将构造函数的
this绑定到新创建的对象
- 将构造函数的
- 处理返回值
- 如果构造函数显示返回了一个对象
return {...}, 则new操作的结果是这个返回的对象 - 如果构造函数没有返回值,或者返回非对象的值(例如
return 42或者return undefined),则返回新创建的对象
- 如果构造函数显示返回了一个对象
- 返回新对象
- 默认情况下,返回步骤 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)拓展
- 箭头函数没有自己的
this和prototype,因此不能使用new