真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

深入淺析javascript繼承體系

最近做web項(xiàng)目,接觸了jquery等框架,雖然使用方便,但是還是想學(xué)習(xí)下Javascript,今天分享下最近對(duì)js原型繼承的理解,不足之處歡迎指正。

創(chuàng)新互聯(lián)總部坐落于成都市區(qū),致力網(wǎng)站建設(shè)服務(wù)有網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、網(wǎng)絡(luò)營(yíng)銷策劃、網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站維護(hù)、公眾號(hào)搭建、小程序開(kāi)發(fā)、軟件開(kāi)發(fā)等為企業(yè)提供一整套的信息化建設(shè)解決方案。創(chuàng)造真正意義上的網(wǎng)站建設(shè),為互聯(lián)網(wǎng)品牌在互動(dòng)行銷領(lǐng)域創(chuàng)造價(jià)值而不懈努力!

一、構(gòu)造器的原型屬性與原型對(duì)象

剛接觸js時(shí)通常依樣畫瓢,用函數(shù)new一個(gè)實(shí)例,也不知道其原因,只聽(tīng)說(shuō)js中函數(shù)即對(duì)象。原來(lái)js中沒(méi)有采用Java等語(yǔ)言中的類繼承體系,而是使用原型對(duì)象(prototype)實(shí)現(xiàn)繼承體系,具體說(shuō)是利用“構(gòu)造器”實(shí)現(xiàn)類的功能。

首先解釋下原型繼承中的兩個(gè)重要概念:原型屬性、原型對(duì)象(實(shí)例)。

就js對(duì)象系統(tǒng)而言,創(chuàng)建的每個(gè)函數(shù)(構(gòu)造器)都有一個(gè)prototype原型屬性,同時(shí),通過(guò)構(gòu)造器創(chuàng)建的每個(gè)對(duì)象實(shí)例也包含一個(gè)_proto_屬性,prototype和_proto_屬性是一個(gè)指針,指向原型對(duì)象。普通函數(shù)與構(gòu)造函數(shù)的唯一區(qū)別就是,其原型屬性prototype是不是一個(gè)有意義的值。

原型屬性prototype所指向的原型是一個(gè)對(duì)象實(shí)例(Object instance)。具體如下圖所示,若構(gòu)造器Animal()有一個(gè)原型對(duì)象B,則由該構(gòu)造器創(chuàng)建的實(shí)例都必然復(fù)制于B。即:Animal()的實(shí)例a1的_proto_屬性也會(huì)指向原型對(duì)象B。因此,實(shí)例a1能夠繼承B的所有屬性、方法和其他性質(zhì)。

深入淺析javascript繼承體系

圖1 js對(duì)象實(shí)例化實(shí)現(xiàn)

二、空的對(duì)象

在javascript中,“空的對(duì)象”是整個(gè)原型繼承體系的根基,是所有對(duì)象的基礎(chǔ)。介紹“空的對(duì)象”之前,必須先介紹下“空對(duì)象(null)”。

空對(duì)象null

null不是“空的對(duì)象”,作為javascript中的一個(gè)保留字,其含義是:

(1)屬于對(duì)象類型

(2)對(duì)象是空值

作為一個(gè)對(duì)象類型,可以使用for…in去列舉它,但是作為一個(gè)空值,null沒(méi)有任何方法和屬性(包括constructor、_proto_等屬性),因此列舉不到任何內(nèi)容。如下例所示:

var num=0;
  for(var propertyName in null)
  {
  num++;
  }

Alert(num);//顯示值為0

最重要的一點(diǎn)是null沒(méi)有原型,它并不是自O(shè)bject()構(gòu)造器(或其子類)實(shí)例化而來(lái),對(duì)其進(jìn)行instanceof 運(yùn)算會(huì)返回false。

2.“空的對(duì)象”

“空的對(duì)象”是指一個(gè)標(biāo)準(zhǔn)的、通過(guò)Object()構(gòu)造的對(duì)象實(shí)例。例如:

obj=new Object();或 obj={};

“空的對(duì)象”具有“對(duì)象”的一切特性,因此可以存取toString()、valueof等預(yù)定義的屬性和方法。

3.“空的對(duì)象”與null的關(guān)系

如下圖2中紅線所示路徑,當(dāng)通過(guò)”O(jiān)bject.prototype._proto_”獲取Object原型對(duì)象的-proto-屬性時(shí),將會(huì)得到”null”,由于null對(duì)象沒(méi)有任何屬性,也就是說(shuō)”O(jiān)bject {}”

原型對(duì)象就是原型鏈的終點(diǎn)了。

深入淺析javascript繼承體系

圖2 js類繼承體系

三、Javascript繼承的實(shí)現(xiàn)以及原型鏈維護(hù)

(1)繼承的實(shí)現(xiàn)

第一節(jié)說(shuō)過(guò)javascript中類繼承是通過(guò)修改構(gòu)造函數(shù)的原型屬性prototype實(shí)現(xiàn)的。如下代碼所示:

function Animal() {
this.name = 'Animal';
};
function Dog() {
};
  Dog.prototype = new Animal();
var d = new Dog();
console.log(d.name);//'Animal'

通過(guò)創(chuàng)建一個(gè)Animal類型的實(shí)例并將其賦值給構(gòu)造函數(shù)Dog()的prototype屬性,從而實(shí)現(xiàn)類型繼承,即Animal是Dog的父類。這樣Dog類型的實(shí)例d也能訪問(wèn)Animal類型的name屬性。

(2)原型鏈

JS對(duì)象繼承體系中有兩種原型鏈:“內(nèi)部原型鏈”和“構(gòu)造器原型鏈”。如圖3所示,黑色箭頭指示路徑是通過(guò)構(gòu)造函數(shù)的prototype屬性保持的“構(gòu)造器原型鏈”。紅色箭頭指示路徑是通過(guò)對(duì)象實(shí)例的_proto_屬性保持的“內(nèi)部原型鏈”。

深入淺析javascript繼承體系

圖3 原型鏈

(3)原型鏈維護(hù)

圖3說(shuō)明構(gòu)造器通過(guò)顯示的prototype構(gòu)建了一個(gè)原型鏈,而對(duì)象實(shí)例也通過(guò)_ proto _屬性構(gòu)建了一個(gè)原型鏈。由于_ proto _是一個(gè)不可訪問(wèn)的內(nèi)部屬性(Chrome中可以查看對(duì)象_ proto _屬性的值,但不可以修改),因此無(wú)法從子類(Dog)的實(shí)例dog1開(kāi)始訪問(wèn)整個(gè)原型鏈。因此,我們需要從圖3中的“內(nèi)部原型鏈”和“構(gòu)造器原型鏈”中找到一個(gè)連接點(diǎn),使得實(shí)例不能訪問(wèn)obj._proto_的情況下通過(guò)構(gòu)造器訪問(wèn)內(nèi)部原型鏈(將兩種原型鏈串聯(lián)起來(lái))。

若要從子類的實(shí)例開(kāi)始訪問(wèn)整個(gè)原型鏈,需要使用實(shí)例的constructor屬性維護(hù)原型鏈。

其實(shí),JavaScript已經(jīng)為構(gòu)造器維護(hù)了原型屬性,根據(jù)如下測(cè)試代碼,當(dāng)我們自定義一個(gè)構(gòu)造器時(shí),其原型對(duì)象是一個(gè)Object()類型的實(shí)例,但是其原型對(duì)象的constructor屬性默認(rèn)總是指向構(gòu)造器自身,而非指向其父類Object。如圖4中構(gòu)造器實(shí)例中藍(lán)色框中的constructor屬性,該constructor屬性繼承自原型對(duì)象,因此可以得出一個(gè)自定義的構(gòu)造器產(chǎn)生的實(shí)例,其constructor屬性默認(rèn)總是指向該構(gòu)造器。

function Animal() {
};
var a = new Animal();
console.log(Animal.prototype);//Object(){}
console.log(Animal.prototype.constructor === Animal);//true//true

深入淺析javascript繼承體系

圖4

因此,在_proto_屬性不可訪問(wèn)時(shí),可通過(guò)a1.constructor.prototype獲取實(shí)例a1的原型對(duì)象。然而,當(dāng)我們自定義一個(gè)構(gòu)造函數(shù)Dog(),并且手動(dòng)指定其prototype屬性值為Animal,即指定Dog的父類為Animal。此時(shí)訪問(wèn)d1.constructor值為Animal,而不是Dog;由圖5可以看出,Dog的原型對(duì)象和dog分別由Animal()和Dog()兩個(gè)不同的構(gòu)造器產(chǎn)生,然而他們的constructor屬性指向了相同的構(gòu)造器(Animal),這樣就與使用constructor屬性串聯(lián)兩種原型鏈的設(shè)想沖突了。

深入淺析javascript繼承體系

圖5

是構(gòu)造器出問(wèn)題還是原型出了問(wèn)題?圖5可以看出,原型繼承要求的“復(fù)制行為”已經(jīng)正確實(shí)現(xiàn),能夠從子類實(shí)例中訪問(wèn)原型對(duì)象屬性,問(wèn)題是在給子類構(gòu)造器Dog()賦予一個(gè)原型對(duì)象時(shí)應(yīng)該“修正”該原型對(duì)象的構(gòu)造屬性值(constructor)。ECMAScript 3標(biāo)準(zhǔn)提供的方法是:保持原型的構(gòu)造器屬性,在子類構(gòu)造器中初始化其實(shí)例對(duì)象的構(gòu)造屬性。代碼如下: 

function Dog () {
  //初始化constructor屬性
   this.constructor=Dog; //或 this.constructor=arguments.callee;
  };
  Dog.prototype = new Animal();//賦予原型對(duì)象,實(shí)現(xiàn)繼承

深入淺析javascript繼承體系

圖6

對(duì)constructor屬性“修正”后效果如圖6所示,在子類構(gòu)造器Dog中初始化其實(shí)例對(duì)象的constructor屬性后,Dog的實(shí)例對(duì)象的constructor都指向Dog,而Dog的原型對(duì)象的constructor仍然指向父類型構(gòu)造器Animal。這樣就可以實(shí)現(xiàn)利用constructor屬性串聯(lián)起原型鏈,可以從子類實(shí)例開(kāi)始回溯整個(gè)原型鏈。

總結(jié)

以上所述是小編給大家介紹的javascript繼承體系的相關(guān)知識(shí),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)創(chuàng)新互聯(lián)網(wǎng)站的支持!


當(dāng)前標(biāo)題:深入淺析javascript繼承體系
網(wǎng)頁(yè)網(wǎng)址:http://weahome.cn/article/iphegj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部