精品伊人久久大香线蕉,开心久久婷婷综合中文字幕,杏田冲梨,人妻无码aⅴ不卡中文字幕

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
原型-盡人事以聽天命

原型

在使用JavaScript的面向?qū)ο缶幊讨校蛯ο笫莻€(gè)核心概念。在JavaScript中對象是作為現(xiàn)有示例對象(即原型)的副本而創(chuàng)建的,該名稱就來自于這一概念。此原型對象的任何屬性和方法都將顯示為從原型的構(gòu)造函數(shù)創(chuàng)建的對象的屬性和方法。可以說,這些對象從其原型繼承了屬性和方法。當(dāng)您創(chuàng)建如下所示的新Dog對象時(shí):

 

Js代碼
  1. var buddy = new Dog('Buddy');  

 

buddy所引用的對象將從它的原型繼承屬性和方法,盡管僅從這一行可能無法明確判斷原型來自哪里,對象buddy的原型來自構(gòu)造函數(shù)(在這里是函數(shù)Dog)的屬性。

在JavaScript中,每個(gè)函數(shù)都有名為"prototype"的屬性,用于引用原型對象。此原型對象又有名為"constructor"的屬性,它反過來引用函數(shù)本身。這是一種循環(huán)引用,圖3更好地說明了這種循環(huán)關(guān)系。



 圖 3 每個(gè)函數(shù)的原型都有一個(gè) Constructor 屬性 

現(xiàn)在,通過"new"運(yùn)算符用函數(shù)(上面示例中為Dog)創(chuàng)建對象時(shí),所創(chuàng)建的對象將繼承Dog.prototype屬性。在圖3中,可以看到Dog.prototype對象有一個(gè)回指Dog函數(shù)的構(gòu)造函數(shù)屬性。這樣,每個(gè)Dog對象(從Dog.prototype繼承而來)都有一個(gè)回指Dog函數(shù)的構(gòu)造函數(shù)屬性。圖4中的代碼證實(shí)了這一點(diǎn)。圖5顯示了構(gòu)造函數(shù)、原型對象以及它們創(chuàng)建的對象之間的這一關(guān)系。

Js代碼
  1. var spot = new Dog(“Spot”);   
  2.   
  3. // Dog.prototype is the prototype of spot   
  4. alert(Dog.prototype.isPrototypeOf(spot)); // 說明spot對象是從原型繼承來的   
  5.   
  6. // spot inherits the constructor property   
  7. // from Dog.prototype   
  8. alert(spot.constructor == Dog.prototype.constructor);    
  9. /*  
  10.  * 上例說明:  
  11.  * 說明構(gòu)造函數(shù)都有一個(gè)名為"prototype"的屬性,該屬性指向原型,   
  12.  * 而原型又有一個(gè)指向構(gòu)造函數(shù)的屬性"constructor",很顯然這是  
  13.  * 一個(gè)圈(循環(huán)引用)。  
  14.  */    
  15. alert(spot.constructor == Dog);    
  16. /*  
  17.  * 上例說明:  
  18.  * 因?yàn)槊總€(gè)對象都繼承自原型,所以每個(gè)對象都從原型中繼承了constructor  
  19.  * 屬性,而這個(gè)屬性指向構(gòu)造函數(shù)。  
  20.   */  
  21.   
  22. // But constructor property doesn’t belong   
  23. // to spot. The line below displays “false”   
  24. alert(spot.hasOwnProperty(“constructor”));    
  25.   
  26. // The constructor property belongs to Dog.prototype   
  27. // The line below displays “true”   
  28. alert(Dog.prototype.hasOwnProperty(“constructor”));   
  29.   
  30. / *   
  31.   * 上面兩個(gè)例子第一個(gè)alert彈出的提示是false,第二個(gè)是true,   
  32.   * 這再次說明了,"constructor"屬性不是對象本身的屬性,   
  33.   * 而是來自于對象的原型。   
  34.   */  

 



 圖 5 實(shí)例繼承其原型

某些讀者可能已經(jīng)注意到圖4中對hasOwnProperty和isPrototypeOf方法的調(diào)用。這些方法是從哪里來的呢〉它們不是來自Dog.prototype。實(shí)際上,在Dog.prototype和Dog實(shí)例中還可以調(diào)用其他方法,比如:toString()、toLocaleString和valueOf,但它們都不來自Dog.prototype。您會(huì)發(fā)現(xiàn),就像.NET Framework中的System.Object充當(dāng)所有類的最終基類一樣,JavaScript中的Object.prototype是所有原型的最終基礎(chǔ)原型。(Object.prototype的原型是null)

在此示例中,請記住Dog.prototype是對象。它是通過調(diào)用Object構(gòu)造函數(shù)創(chuàng)建的(盡管它不可見):

Js代碼
  1. Dog.prototype = new Object();  

 因此,正如Dog實(shí)例繼承Dog.prototype一樣,Dog.prototype繼承Object.prototype。這使得所有Dog實(shí)例也繼承了Object.prototype的方法和屬性。所以每個(gè)Dog實(shí)例也就繼承了我們上面說的toString、toLocaleString、hasOwnProperty方法了。

每個(gè)JavaScript對象都繼承一個(gè)原型鏈,而所有原型都終止于Object.prototype。注意,迄今為止您看到的這種繼承是活動(dòng)對象之間的繼承。它不同于繼承的常見概念,后者是指在聲明類時(shí)類之間的發(fā)生的繼承,因此,JavaScript繼承動(dòng)態(tài)性更強(qiáng)。它使用簡單算法實(shí)現(xiàn)這一點(diǎn),如下所示:當(dāng)您嘗試訪問對象的屬性/方法時(shí),JavaScript將檢查該屬性/方法是否是在該對象中定義的。如果不是,則檢查對象的原型,如果還不是,則檢查該對象的原型的原型,如此繼續(xù),一直檢查到Object.prototype。圖6說明了此解析過程。


圖 6 在原型鏈中解析 toString() 方法

JavaScript動(dòng)態(tài)地解析屬性訪問和方法調(diào)用的方式產(chǎn)生了一些特殊效果:

  • 繼承原型對象的對象上可以立即呈現(xiàn)對原型所作的更改,即使是在創(chuàng)建這些對象之后。
  • 如果在對象中定義了屬性/方法 X,則該對象的原型中將隱藏同名的屬性/方法。例如:通過在Dog.prototype中定義toString方法,可以改寫Object.prototype的toString方法。
  • 更改只沿一個(gè)方向傳遞,即從原型到它的派生對象,但不能沿相反方向傳遞。

圖7說明了這些效果。圖7還顯示了如何解決前面遇到的不需要的方法實(shí)例的問題。通過將方法放在原型內(nèi)部,可以使對象共享方法,而不必使每個(gè)對象都有單獨(dú)的函數(shù)對象實(shí)例。在此示例中,rover和spot共享getBreed方法,直至在spot中以任何方式改寫toString方法。此后,spot有了它自己版本getBreed方法,但rover對象和用新GreatDane創(chuàng)建的后續(xù)對象仍共享在GreatDane.prototype對象中定義的那個(gè)getBreed方法實(shí)例。

Figure 7  繼承原型

Js代碼
  1. function GreatDane() { }   
  2.   
  3. var rover = new GreatDane();   
  4. var spot = new GreatDane();   
  5.   
  6. GreatDane.prototype.getBreed = function() {   
  7.     return 'Great Dane';   
  8. };   
  9.   
  10. // Works, even though at this point   
  11. // rover and spot are already created.   
  12. alert(rover.getBreed());   
  13.   
  14. // this hides getBreed() in GreatDane.prototype   
  15. spot.getBreed = function() {   
  16.     return 'Little Great Dane';   
  17. };   
  18. alert(spot.getBreed());    
  19.   
  20. // but of course, the change to getBreed    
  21. // doesn’t propagate back to GreatDane.prototype   
  22. // and other objects inheriting from it,   
  23. // it only happens in the spot object   
  24. alert(rover.getBreed());  
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JavaScript: 使用面向?qū)ο蟮募夹g(shù)創(chuàng)建高級(jí) Web 應(yīng)用程序
JS原型與原型鏈終極詳解
修改構(gòu)造函數(shù)原型——JavaScript中的對象(二)
JavaScript中的原型和原型鏈
es6—— 繼承 ——類的 prototype 屬性和__proto__屬性(原型鏈)
博客園 - 鳥食軒 - JScript中的prototype(原型)屬性研究(1)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

主站蜘蛛池模板: 静海县| 永丰县| 潼南县| 体育| 马关县| 新兴县| 德庆县| 大渡口区| 鄂托克前旗| 东港市| 贵阳市| 龙游县| 大渡口区| 呼伦贝尔市| 泸水县| 沽源县| 和平县| 玉门市| 象山县| 广东省| 华亭县| 乌海市| 太康县| 县级市| 台北县| 盐山县| 南投县| 屏东市| 大厂| 长顺县| 台江县| 如皋市| 柳河县| 乾安县| 米脂县| 达日县| 新营市| 溆浦县| 广饶县| 密山市| 景宁|