原型
我們創(chuàng)建的每一個(gè)函數(shù)都有一個(gè)prototype(原型)屬性。這個(gè)屬性是一個(gè)指針,指向一個(gè)對象,而這個(gè)對象的用途是包含可以由特定類型的所有實(shí)例共享的屬性和方法。即protptype就是通過調(diào)用構(gòu)造函數(shù)而創(chuàng)建的那個(gè)對象實(shí)例的原型對象。
//示例
function Persion () {};
Persion.prototype.name= "Tom";
Persion.prototype.age= 25;
Persion.prototype.sayName= function () {
console.log(this.name);
};
var persion1= new Persion();
var persion2= new Persion();
console.log(persion1.sayName === persion2.sayName); //true
/*
*上面的代碼中,persion1和persion2都是函數(shù)Persion的實(shí)例,
*它們的原型對象都是Persion.prototype,
*所以等式成立
*/

構(gòu)造函數(shù)--原型對象--實(shí)例關(guān)系圖.png
原型鏈
-
查找對象屬性的過程:
首先從對象實(shí)例本身開始。如果在實(shí)例中找到了具有給定名字的屬性,則返回該屬性的值;如果沒有找到,則繼續(xù)搜索指針指向的原型對象,在原型對象中查找具有給定名字的屬性。如果在原型對象中找到這個(gè)屬性,則返回該屬性的值。
//示例
var Dog= function () {};
Dog.prototype.price= 2000;
var husky= new Dog();
console.log(husky.price); //2000
console.log(Dog.price); //undefined
/*
*查找對象屬性不會去查詢自身prototype對象,
*而是查找[[Prototype]]指針指向的對象。
*/
- 構(gòu)造函數(shù)、原型、實(shí)例之間的關(guān)系:
每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對象,原型對象都包含一個(gè)指向構(gòu)造函數(shù)的指針;而實(shí)例都包含一個(gè)指向原型對象的內(nèi)部指針。
var Dog= function () {};
var husky= new Dog();
husky.price= 2000;
console.log(husky.price); //2000
console.log(Dog.price); //undefined
/*
*實(shí)例與構(gòu)造函數(shù)沒有連接。
*實(shí)例與構(gòu)造函數(shù)的原型對象存在一個(gè)連接。(內(nèi)部指針[[Prototype]])
*/
如果讓原型對象等于另一個(gè)類型的實(shí)例,那么此時(shí)的原型對象將包含一個(gè)指向另一個(gè)原型的指針,相應(yīng)的,另一個(gè)原型中也包含著一個(gè)指向另一個(gè)構(gòu)造函數(shù)的指針。假如另一個(gè)原型又是另一個(gè)類型的實(shí)例,上述關(guān)系依然成立,如此層層遞進(jìn),就構(gòu)成了實(shí)例與原型的鏈條。這就是原型鏈的基本概念。
function Base () {
this.a= 2;
}
Base.prototype.add= function (x,y) {
return x+y;
}
function Super () {
this.b= 1;
}
Super.prototype= new Base();
Super.prototype.subtract= function(x,y){
return x-y;
}
function Sub () {
this.name= "sub";
}
Sub.prototype= new Super();
Sub.prototype.sayName= function () {
console.log(this.name);
}
var s= new Sub();
for(var k in s){
console.log(k);
}
//name
//b
//sayName
//a
//subtract
//add

原型層次圖.png
這張圖片標(biāo)明了實(shí)例s所有可枚舉的方法所屬于的原型對象。

原型指向圖.png
驗(yàn)證一下掌握的情況:
var Animal= function () {};
var Dog= function () {};
Animal.price= 2000;
Dog.prototype= Animal;
var husky= new Dog();
console.log(husky.price); //2000
console.log(Dog.price); //undefined
參考資料
《JavaScript高級程序設(shè)計(jì)(第3版)》
《原型原型鏈》---湯姆大叔
《原型原型鏈終極詳解》