new 操作符的作用
實例化出一個新的對象,并將新對象的原型對象指向
當(dāng)前構(gòu)造函數(shù)的原型或者Object.prototype
新對象的原型對象指向當(dāng)前構(gòu)造函數(shù)的原型
function Person(name, age) {
this.name = name
this.age = age
}
const p1 = new Person('Tom', 23)

運(yùn)行結(jié)果
新對象的原型對象指向 Object.prototype
function Person(name, age) {
this.name = name
this.age = age
return { name, age }
}
const p1 = new Person('Tom', 23)

運(yùn)行結(jié)果
當(dāng)返回值不是 Object 實例的時候自動忽略
function Person(name, age) {
this.name = name
this.age = age
return 2
}
const p1 = new Person('Tom', 23)

運(yùn)行結(jié)果
new 操作符的實現(xiàn)思路
- 創(chuàng)建一個新的對象
- 添加屬性
- 指定原型對象
- 如果構(gòu)造函數(shù)沒有返回對象,就返回新建的對象
function myNew(target) {
// 新建一個對象
const obj = Object.create({})
// 添加屬性
const result = target.apply(obj, Array.prototype.slice.call(arguments, 1))
// 指定原型對象
Object.setPrototypeOf(obj, target.prototype)
// or
// obj.__proto__ = target.prototype
// 如果構(gòu)造函數(shù)沒有返回對象,就返回新建的對象
return result instanceof Object ? result : obj
}
const p2 = myNew(Person, 'Skill', 23)

運(yùn)行結(jié)果
為什么不使用 obj.proto = Object.create(target.prototype) 綁定原型對象
先看下使用 obj.proto = Object.create(target.prototype) 綁定原型對象的結(jié)果
function myNew(target) {
// 新建一個對象
const obj = Object.create({})
// 添加屬性
const result = target.apply(obj, Array.prototype.slice.call(arguments, 1))
// 指定原型對象
obj.__proto__ = Object.create(target.prototype)
// 如果構(gòu)造函數(shù)沒有返回對象,就返回新建的對象
return result instanceof Object ? result : obj
}
const p2 = myNew(Person, 'Skill', 23)

運(yùn)行結(jié)果
多了一層的原因是因為 Object.create(target) 是基于目標(biāo)對象(target)創(chuàng)建出一個實例
【筆記不易,如對您有幫助,請點贊,謝謝】