寫在前面
new 操作符具體做了什么,推薦看阮一峰的 實例對象與 new 命令,看完整個人神清氣爽。
new 操作符是在 js 中一直就有的,是 js 面前對象開發的重要操作符。我們經常使用 new 創建一個對象實例,那么 new 操作符具體做了什么?
這里做簡單介紹如下。
1. 創建了一個空對象,作為要返回的實例對象
首先,new 操作符肯定返回了一個對象,而且這個對象是按照其構造函數要求的樣子進行構造的。
2. 將空對象的原型 _proto_ 指向構造函數的 prototype 屬性
創建的空對象是 let obj = new Object()
或 let obj = {}
,該對象的原型 _proto_ 是 Object,但是我們使用自定義的構造函數創建對象實例時會多一層自定義的原型,就是構造函數中的 prototype 屬性對應的用於存放公有屬性的對象。因此 new 操作符就改變了新創建的對象的原型鏈。
3. 以指定構造函數的 this 為新創建的對象的方式調用構造函數
我們在使用 new 操作符進行創建對象實例后,會發現該對象已經帶有了自己的某些屬性,那么這些自己的屬性是哪里來的呢?
答案是在構造函數構造出來的,構造函數內部有一個 this 對象,並且會發現在構造函數內有為 this 對象賦值的一個情況,如 this.age = 18
等等,我們知道,函數中 this 在沒有進行指定的情況下會默認是調用該函數的對象。但是 this 是可以指定的,使用函數的 call 或 apply 方式進行函數的調用可以指定函數內的 this ,因此,new 操作符在調用構造函數的時候,將構造函數的 this 指定為新創建的對象,那么構造函數內帶有 this 的語句就是在構造該對象的屬性。因此 new 操作符肯定以指定 this 的方式調用了構造函數。
4. 判斷構造函數返回值類型返回對象
構造函數也是函數,當然可以有返回值,但 new 操作符在調用構造函數時,規定如果構造函數沒有指定返回值或者返回值為值類型,new 就會返回新創建的對象,new Fn() 拿到的就是新創建的對象實例,但如果構造函數返回的是一個對象,那 new 就會返回構造函數返回的對象,而不是對象實例了。