轉自:http://blog.csdn.net/wxw_317/article/details/49617767
在 JavaScript 中,原型也是一個對象,通過原型可以實現對象的屬性繼承,JavaScript 的對象中都包含了一個 prototype
內部屬性,這個屬性所對應的就是該對象的原型。
prototype
作為對象的內部屬性,是不能被直接訪問的。所以為了方便查看一個對象的原型,Firefox 和 Chrome 中提供了 __proto__
這個非標準(不是所有瀏覽器都支持)的訪問器:
function Person(name, age) {
this.name = name;
this.age = age;
this.getInfo = function(){
console.log(this.name + " is " + this.age + " years old");
};
}
var will = new Person("Will", 28);
// 測試:
will.name; // "Will"
will.age; // 28
will.getInfo(); // Will is 28 years old
在上面的代碼中,通過了 Person 這個 構造函數 創建了一個 will 對象。下面就通過 will 這個對象一步步展開了解原型。
查看對象 will 的原型
will.__proto__
// 結果:
Object {}
constructor:Person(name, age)
__proto__:Object
person {}
對象就是對象 will 的原型,通過 Chrome 展開可以看到,person {}
作為一個原型對象,也有 __proto__
屬性(對應原型的原型)。
will.constructor
// 結果
function Person(name, age){
this.name = name;
this.age = age;
this.getInfo = function(){
console.log(this.name + " is " + this.age + " years old");
};
}
在 JavaScript 的原型對象中,還包含一個 constructor
屬性,這個屬性對應創建所有指向該原型的實例的構造函數。
在這里,will 對象本身并沒有 constructor
這個屬性,但是通過原型鏈查找,找到了 will 原型(will.__proto__
)的 constructor
屬性,并得到了 Person 函數。
查看對象 will 的原型(will.__proto__)的原型
will.__proto__ === Person.prototype; // true
Person.prototype.constructor === Person; // true
在 JavaScript 中,每個函數都有一個 prototype
屬性,當一個函數被用作構造函數來創建實例時,該函數的 prototype
屬性值將被作為原型賦值給所有對象實例(也就是設置實例的 __proto__
屬性)。也就是說,所有實例的原型引用的是函數的 prototype 屬性。
這里我們用 Person 函數作為構造函數創建了實例 will,will 的原型(will.__proto__
)指向函數 Person 的 prototype
屬性(Person.prototype
),所以結果為 true
。
注意: prototype
屬性是函數對象特有的,如果不是函數對象,將不會有這樣一個屬性。
// 對象本身是不具有 prototype 屬性的
will.Prototype
// 結果
undefined
當通過 Person.prototype.__proto__
語句獲取 will 對象原型的原型時候,將得到 Object {}
對象,后面將會看到所有對象的原型都將追溯到 Object {}
對象。
對于原型對象 Person.prototype
的 constructor
,根據前面的介紹,將對應 Person 函數本身。
通過上面可以看到,Person.prototype
對象和 Person
函數對象通過 constructor
和 prototype
屬性實現了相互引用。