new的實現原理


關鍵字new在調用構造函數的時候實際上進行了如下的幾個步驟:

  1. 創建一個新的對象
  2. 將構造函數的作用域賦值給這個新的對象(因此this指向了這個新的對象)
  3. 執行構造函數中的代碼(為這個新對象添加屬性)
  4. 返回新對象

我們寫一個函數,命名為objectFactory,來模擬new的效果,使用的時候像下面這樣:

function Person () {
    ……
}

// 使用 new
var student = new Person(……);
// 使用 objectFactory
var student = objectFactory(Person, ……)

接下來,我們按照new調用構造函數的四個步驟來實現objectFactory:

function objectFactory() {
    // 創建一個新的對象
    const obj = {}    
    // 獲取第一個參數,arguments是類數組,不可直接調用shift方法
    //此外因為 shift 會修改原數組,所以 arguments 會被去除第一個參數
    const Constructor = [].shift.call(arguments)  
    // 將obj的原型指向構造函數的原型對象,這樣obj就可以訪問構造函數原型上的屬性
    obj.__proto__ = Constructor.prototype   
    // 將構造函數的this指向obj,這樣obj就可以訪問到構造函數中的屬性
    Constructor.apply(obj, arguments);
    // 返回 obj
    return obj;
}

如果構造函數中返回了一個對象,則在實例中只能訪問到返回的對象中的屬性。

所以我們還需要判斷返回的值是不是一個對象,如果是一個對象,我們就返回這個對象,如果沒有,我們該返回什么就返回什么。

function objectFactory() {
    const obj = {}    
    const Constructor = [].shift.call(arguments)  
    obj.__proto__ = Constructor.prototype   
    const res = Constructor.apply(obj, arguments);
    return typeof res === 'object' ? res : obj;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM