構(gòu)造函數(shù)名一般為大寫字母開頭,與new運算符一起使用來實例化對象。
// 構(gòu)造函數(shù)
function Person() {
this.name = 'Denise'
}
// 創(chuàng)建對象(實例化)
var p = new Person()
// 打印出來看看
console.log(Person.prototype)
console.log(p)
什么是原型呢?
構(gòu)造函數(shù)在創(chuàng)建的過程中,系統(tǒng)自動創(chuàng)建出來與構(gòu)造函數(shù)相關聯(lián)的一個空的對象??梢杂蓸?gòu)造函數(shù).prototype 來訪問到。如上述代碼,在實例化對象p的過程中,系統(tǒng)就自動創(chuàng)建出了構(gòu)造函數(shù)的原型 Person.prototype。

每個對象的 __proto__ 屬性指向自身構(gòu)造函數(shù)的prototype。如上述代碼,對象p的 __proto__ 指向 Person.prototype。
constructor屬性是原型對象Person.prototype的屬性,指向這個原型對象所對應的構(gòu)造函數(shù),即Person。

關鍵在于 __proto__ ,那 __proto__ 到底是什么呢?
簡單來說,每個對象都會有一個 __proto__ 屬性,當我們訪問一個對象的屬性時,如果這個對象本身不存在這個屬性,那么它就會去 __proto__ 里找這個屬性,這個 __proto__ 又會有自己的 __proto__ ,于是就這樣一直找下去,這就是所謂的原型鏈。
在上面這個例子中的p對象的原型鏈結(jié)構(gòu)圖如下:
p -----> Person.prototype (p.__proto__) -------> Object.prototype (p.__proto__.__proto__) ---------> null
那么,new 到底做了什么?
// 構(gòu)造函數(shù)
function Person() {
this.name = 'Denise'
}
// 創(chuàng)建對象(實例化)
var p = new Person()
// 模擬推導過程 -->
var p = {};
p.__proto__ = Person.prototype;
Person.call(p);
1.創(chuàng)建一個空對象 p
2.把這個空對象 p 的屬性 __proto__ 指向函數(shù) Person 的 prototype
3.將構(gòu)造函數(shù) Person 的作用域賦給新對象 p,即 this 指向了 p
4.執(zhí)行Person 中的代碼,為p添加屬性 name
5.返回新對象