国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

理解Javascript_05_原型繼承原理

2019-11-21 00:12:31
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
prototype與[[prototype]]

在有面象對(duì)象基礎(chǔ)的前提下,來(lái)看一段代碼:
復(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)在讓我們來(lái)解釋一下這張內(nèi)存圖的來(lái)龍去脈:

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

  那先來(lái)看prototype,每一個(gè)函數(shù)對(duì)象都有一個(gè)顯示的prototype屬性,它代表了對(duì)象的原型,更明確的說(shuō)是代表了由函數(shù)對(duì)象(構(gòu)造函數(shù))所創(chuàng)建出來(lái)的對(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),這就是原型鏈的概念。額外要說(shuō)的是:不同的JS引擎實(shí)現(xiàn)者可以將內(nèi)部[[Prototype]]屬性命名為任何名字,并且設(shè)置它的可見(jiàn)性,前且只在JS引擎內(nèi)部使用。雖然無(wú)法在JS代碼中訪問(wèn)到內(nèi)部[[Prototype]](FireFox中可以,名字為_(kāi)_proto__因?yàn)镸ozilla將它公開(kāi)了),但可以使用對(duì)象的 isPrototypeOf()方法進(jìn)行測(cè)試,注意這個(gè)方法會(huì)在整個(gè)Prototype鏈上進(jìn)行判斷。

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

屬性訪問(wèn)原則

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

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

結(jié)合是上面的理論,讓我們?cè)賮?lái)看一個(gè)更加復(fù)雜的示例,他明確的解釋了prototype、[[prototype]]、原型鏈以及屬性訪問(wèn)的相關(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ù)上面的代碼,你能畫(huà)出相應(yīng)的內(nèi)存圖嗎?好,讓我們來(lá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),通過(guò)內(nèi)存來(lái)展現(xiàn)程序內(nèi)部運(yùn)行細(xì)節(jié)真的是太完美了!
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 莒南县| 句容市| 永城市| 玉龙| 宁城县| 焦作市| 霸州市| 交口县| 浑源县| 吉木萨尔县| 汝阳县| 奉化市| 泸定县| 乐安县| 东至县| 冷水江市| 太谷县| 京山县| 萍乡市| 长沙县| 西平县| 确山县| 兰坪| 临清市| 青浦区| 太谷县| 安岳县| 内江市| 牡丹江市| 克山县| 永登县| 中牟县| 米泉市| 梨树县| 平安县| 台东市| 尖扎县| 新郑市| 大港区| 奎屯市| 镇平县|