在js中,咱們常常會用到 new 操做符,當咱們對構造函數使用new操做符時,具體作了哪些事情呢?函數
它會完成如下四個步驟:this
1.建立一個空的對象spa
2.設置原型鏈:將新對象的constructor屬性設置爲構造函數信息,設置新對象的__proto__屬性指向構造函數的prototype對象prototype
3.讓構造函數中的this指向新對象,並執行構造函數的函數體對象
4.判斷構造函數的返回值類型,將初始化完成的對象地址,保存到等號左邊的變量中blog
結合代碼分析:原型鏈
var Func = function() {作用域
...原型
}string
var func = new Func()
咱們來具體分析:
new一共經歷了4個階段:
1.建立一個空對象
var obj = {}
2.設置原型鏈
obj.__proto__ = Func.prototype
3.讓Func中的 this 指向 obj,並執行Func的函數體。(由於建立新的對象後,構造函數的做用域賦給了新對象,因此 this 指向了新對象)
var res = Func.call(obj)
4.判斷Func的返回值類型
若是是基本數據類型,則返回obj,若是是引用數據類型,則返回引用類型的對象
if (typeof(res)=== "object"){
func = res
}else {
func = obj
}
注意:在構造函數沒有返回值的狀況下,返回新建立的對象;
若是構造函數有返回值res,那麼就要判斷值的類型:
返回值res爲基本數據類型(string、number、null、undefined、boolean、symbol),那麼返回新建立的對象。
返回值res爲引用數據類型時,函數的返回值res才爲指定對象,此時返回res。
構造函數沒有返回值的狀況:
構造函數返回值爲基本數據類型的狀況:
構造函數返回值爲引用數據類型的狀況:
由Person {name : "Sunwukong"} 和 {name : "Zhubajie"}
能夠看出,當返回值是引用類型時,則使用 return 的對象,此時 new 操做也失效了。