欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

理解Javascript_05_原型繼承原理

 更新時(shí)間:2010年10月13日 19:34:16   作者:  
對(duì)于面向?qū)ο蟮幕A(chǔ)語法在此我就不重復(fù)了,對(duì)面向?qū)ο蟛皇煜さ呐笥芽梢詤⒖础妒褂妹嫦驅(qū)ο蟮募夹g(shù)創(chuàng)建高級(jí) Web 應(yīng)用程序》一文。
prototype與[[prototype]]

在有面象對(duì)象基礎(chǔ)的前提下,來看一段代碼:
復(fù)制代碼 代碼如下:

//Animal構(gòu)造函數(shù)
function Animal(name){
this.name = name;
}
//Animal原型對(duì)象
Animal.prototype = {
id:"Animal",
sleep:function(){
alert("sleep");
}
}

var dog = new Animal("旺才");
alert(dog.name);//旺才
alert(dog.id);//Animal
dog.sleep()//sleep

其對(duì)應(yīng)的簡(jiǎn)易內(nèi)存分配結(jié)構(gòu)圖:

現(xiàn)在讓我們來解釋一下這張內(nèi)存圖的來龍去脈:

首先明確一點(diǎn)[[prototype]]與prototype并不是同一個(gè)東西。

  那先來看prototype,每一個(gè)函數(shù)對(duì)象都有一個(gè)顯示的prototype屬性,它代表了對(duì)象的原型,更明確的說是代表了由函數(shù)對(duì)象(構(gòu)造函數(shù))所創(chuàng)建出來的對(duì)象的原型。結(jié)合本例,Animal.prototype就是dog的原型,dog所引用的那個(gè)對(duì)象將從Animal.prototype所引用的對(duì)象那繼承屬性與方法。

  每個(gè)對(duì)象都有一個(gè)名為[[Prototype]]的內(nèi)部屬性,指向于它所對(duì)應(yīng)的原型對(duì)象。在本例中dog的[[prototype]]指向Animal.prototype,大家都知道,Animal.prototype也是一個(gè)對(duì)象,即然是一個(gè)對(duì)象,那它必然也有[[prototype]]屬性指向于它所對(duì)應(yīng)的原型對(duì)象,由此便構(gòu)成了一種鏈表的結(jié)構(gòu),這就是原型鏈的概念。額外要說的是:不同的JS引擎實(shí)現(xiàn)者可以將內(nèi)部[[Prototype]]屬性命名為任何名字,并且設(shè)置它的可見性,前且只在JS引擎內(nèi)部使用。雖然無法在JS代碼中訪問到內(nèi)部[[Prototype]](FireFox中可以,名字為__proto__因?yàn)镸ozilla將它公開了),但可以使用對(duì)象的 isPrototypeOf()方法進(jìn)行測(cè)試,注意這個(gè)方法會(huì)在整個(gè)Prototype鏈上進(jìn)行判斷。

注:關(guān)于函數(shù)對(duì)象的具體內(nèi)容,將在后繼的博文中講解。

屬性訪問原則

使用obj.propName訪問一個(gè)對(duì)象的屬性時(shí),按照下面的步驟進(jìn)行處理(假設(shè)obj的內(nèi)部[[Prototype]]屬性名為__proto__):
1. 如果obj存在propName屬性,返回屬性的值,否則
2. 如果obj.__proto__為null,返回undefined,否則
3. 返回obj.__proto__.propName
調(diào)用對(duì)象的方法跟訪問屬性搜索過程一樣,因?yàn)榉椒ǖ暮瘮?shù)對(duì)象就是對(duì)象的一個(gè)屬性值。
提示: 上面步驟中隱含了一個(gè)遞歸過程,步驟3中obj.__proto__是另外一個(gè)對(duì)象,同樣將采用1, 2, 3這樣的步驟來搜索propName屬性。

這就是基于Prototype的繼承和共享。其中object1的方法fn2來自object2,概念上即object2重寫了object3的方法fn2。
JavaScript對(duì)象應(yīng)當(dāng)都通過prototype鏈關(guān)聯(lián)起來,最頂層是Object,即對(duì)象都派生自O(shè)bject類型。

結(jié)合是上面的理論,讓我們?cè)賮砜匆粋€(gè)更加復(fù)雜的示例,他明確的解釋了prototype、[[prototype]]、原型鏈以及屬性訪問的相關(guān)要點(diǎn):
復(fù)制代碼 代碼如下:

//Animal構(gòu)造函數(shù)
function Animal(name){
this.name = name;
}
//Animal原型對(duì)象
Animal.prototype = {
id:"Animal",
sleep:function(){
alert("sleep");
}
}

function Human(name,age){
Animal.call(this,name);
this.age = age;
}

Human.prototype = new Animal();
Human.prototype.id = "Human";

Human.prototype.say = function(){
alert("hello everyone,My name is "+this.name +",I'm "+this.age+" and I'm a "+this.id);
}

//Human相關(guān)調(diào)用
var jxl = new Human('笨蛋',25);
alert(jxl.name);//笨蛋
alert(jxl.id);//Human
jxl.say();//hello everyone,My name is 笨蛋,I'm 25 and I'm a Human

alert(Animal.prototype.isPrototypeOf(jxl));//true
alert(Object.prototype.isPrototypeOf(jxl));//true

根據(jù)上面的代碼,你能畫出相應(yīng)的內(nèi)存圖嗎?好,讓我們來看一下:

注:prototype的根為Object.prototype,對(duì)象Object.prototype的內(nèi)部[[prototype]]屬性為null.
其實(shí),這里還有很多東西可以講,但在其原理都在這張圖上了,可試著調(diào)整一下代碼的次序,如將Human.prototype.id = "Human";放在Human.prototype = new Animal();的前面,看一下運(yùn)行結(jié)果,解釋一下為什么之類的,你可以學(xué)到很多。

我發(fā)現(xiàn),通過內(nèi)存來展現(xiàn)程序內(nèi)部運(yùn)行細(xì)節(jié)真的是太完美了!

相關(guān)文章

最新評(píng)論