首先,我们先来看看 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
操作
- 首先创建一个空对象,这个对象将会作为执行
new 构造函数()
之后,返回的对象实例 - 将上面创建的空对象的原型(
__proto__
),指向构造函数的 prototype 属性 - 将这个空对象赋值给构造函数内部的
this
,并执行构造函数逻辑 - 根据构造函数执行逻辑,返回第一步创建的对象或者构造函数的显式返回值
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)