標籤:
javascript是一門物件導向的語言,但它卻沒有像其他物件導向的語言(如java,C++)有類的概念,也沒有基於類的繼承體系。但是它有自己獨特的繼承方式,那就是基於原型和原型鏈的繼承。
當我們建立一個對象時,每個對象在產生之後都有一個隱式的屬性__proto__(非規範,暫且這麼叫吧),該屬性指向該執行個體的原型對象,並共用其原型對象上的屬性和方法。
下面分析下不同建立對象的方式所對應的__proto__屬性指向的不同。
1.用對象字面量建立對象。
var a={x:1};console.log(a.__proto__);//{}
上面的代碼錶明a對象的__proto__屬性為一個Null 物件,是否意味著用對象字面量建立的對象一開始的__proto__屬性都是指向的一個Null 物件呢?我們看看下面代碼。
var a={x:1};Object.prototype.y=1;console.log(a.__proto__);//{y:1}console.log(a.y);//1
從以上代碼很明顯可以看出,a的__proto__指向的是Object的prototype對象,並且a繼承了Object原型對象上的屬性。所以用對象字面量建立的對象的__proto__屬性指向的是Object的原型對象。
2.用建構函式方法建立對象。
function foo(name){this.name = name;}b=new foo("b");foo.prototype.sayName=function(){ console.log(this.name);}console.log(b.__proto__===foo.prototype);//truecosnsole.log(b.sayName());// b
通過建構函式建立的對象b的__proto__指向foo.prototype。
以上分析了不同方式建立對象的原型對象的不同,接下來說一下原型鏈
從上面的分析我們知道,每個對象都有一個__proto__屬性指向其原型對象,而原型對象本身也是一個對象,它也有一個__proto__屬性指向其原型對象,如此反覆,形成鏈式結構。我們學過鏈表等鏈式結構,此結構必須有一個終點,不然就會構成死鏈。那原型鏈的終點在哪呢?
function foo(name){this.name = name;}b=new foo("b");foo.prototype.sayName=function(){ console.log(this.name);}console.log(foo.prototype.__proto__===Object.prototype)//trueconsole.log(foo.prototype.__proto__.__proto__)//nullconsole.log(foo.prototype.__proto__.__proto__.__proto__)//報錯,null沒有__proto__屬性
foo.prototype對象的__proto__指向的是Object.prototype,而Object.prototype.__proto__屬性值為null,不再有__proto__屬性,也就是說原型鏈就終止於此了。
以此文記錄下自己對原型和原型鏈的認識,歡迎批評指正。
javascript中的原型與原型鏈