new 操作符的背后都做了什么?

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)建出一個實例

【筆記不易,如對您有幫助,請點贊,謝謝】

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容