<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    沒有眼淚
    Don't Cry!
    posts - 13,comments - 44,trackbacks - 0
            眾所周知,javascript中的繼承是通過原型對象(prototype)來實現的.原型對象是由函數的構造函數創建,它所擁有的屬性能被所有對象共享.初始時原型對象指向一個Object對象,并且定義了一個constructor屬性,該屬性指向定義該原型對象的構造函數本身,上述過程可以理解為以下代碼:
    function BaseClass() {
        document.write('This is BaseClass.');
    }
    BaseClass.prototype 
    = new Object();
    BaseClass.prototype.constructor 
    = BaseClass;
    因為原型對象的所有屬性能被構造函數創建對象共享,所以創建的對象可以訪問這里的constructor屬性:
    var c = new BaseClass();
    document.write(c.constructor 
    == BaseClass); //true
    c.constructor(); //調用BaseClass函數,輸出This is BaseClass.
    由于對象本身也可以自定義屬性,所以在讀取對象屬性時js先檢查該對象是否定義了該屬性,如果已經定義了則使用該屬性,如果沒有定義則再從其原型對象中讀取該屬性,所以如果對象自定義的屬性和其原型中的屬性存在重名則自定義屬性"隱藏"了其原型對象中的同名屬性.例:
    c.constructor = function() {
        document.write('This is c');
    }
    c.constructor(); 
    //This is c
    加入上述代碼之后再次調用c.constructor(),則會打印出"This is c".這是因為c已自定義constructor屬性"隱藏"了其原型對象中的constructor屬性.當然js保證了讀寫的不對稱性,也就是說讀取一個對象的屬性時有可能要從其原型對象中去讀取,但寫一個對象的屬性時卻從不涉及其原型對象,無論在一個對象加入或修改多少屬性這都不影響其原型對象中屬性的本來面目.比如這里c自定義了constructor屬性,但這一行為并不影響其原型對象中constructor指向其構造函數這一事實,如果再創建一個對象且不自定義constructor屬性,再調用constructor則依然調用對象的構造函數,例:
    var b = new BaseClass();
    b.constructor(); 
    //調用BaseClass函數,輸出This is BaseClass.

    很容易理解js為什么這樣做,因為一個對象的行為不能影響到其他對象,否則將會造成混亂.
            理解上述規則之后讓我們看看js中是如何通過原型對象實現繼承的.當我們創建一個對象時,可以把該對象看成是由2部分組成的,一部分存儲了該對象自己定義的屬性(稱為A部分),而另一個部分則存儲了其構造函數所定義的原型對象引用(稱為B部分),例如這里的BaseClass.prototype.當讀取對象的屬性時可以分為以下2步:
    1.js先檢查該對象引用所指向的內存區域的A部分是否存在該屬性,如果存在則讀出.
    2.如果沒有則再從B部分存儲的引用(BaseClass.prototype)所指向的內存區域中讀取該屬性.

    從步驟2開始這就是個不斷往上尋找的過程,因為BaseClass.prototype所指向的內存區域也會分為A和B兩個部分,如果再A部分也不存在該屬性,則又會從其B部分所指向的內存區域去尋找該屬性,而該內存區域也有A和B兩個部分,如果A部分仍然不存在,則還要從B部分所指向的內存區域去尋找該屬性,直到達到最頂層的Object類.所以在無形當中就形成了一條鏈,也就是我們常說的原型鏈.如果理解了這個過程我想也就能了解原型對象了.下面簡單分析下b.constructor();的調用過程便于加深理解.
    1.js會在b所指向的內存區域A部分讀取constructor屬性.
    2.當發現沒有該屬性后再從其類的構造函數原型對象引用所指向的內存區域讀取該屬性.因為原型對象引用初始時指向一Object對象內存區域(BaseClass.prototype = new Object();)
    3.再從此Object對象的A部分尋找constructor屬性.
    4.沒有找到該屬性則從其類的原型對象即Object.prototype中去尋找constructor.
    5.如果找到該屬性則調用.
    6.否則,到達鏈的頂端,返回.
    到此能很清楚的知道js中是如何實現繼承的,如果我們自定義的類不想繼承自Object,則可以修改其prototype的指向,可以讓其指向任意一個類,這樣也就實現了繼承自定義類,但js中所有的類都繼承自Object類,所以原型鏈的關系仍然存在.

    posted on 2008-05-09 16:43 zhangchao 閱讀(1048) 評論(3)  編輯  收藏 所屬分類: javascript

    FeedBack:
    # re: 我所理解的原型對象[未登錄]
    2008-12-07 19:10 | simon
    受教  回復  更多評論
      
    # re: 我所理解的原型對象
    2010-06-08 12:41 | #
    非常不錯  回復  更多評論
      
    # re: 我所理解的原型對象
    2013-03-12 15:25 | liger 博客園
    非常的好,情不自禁的轉了  回復  更多評論
      
    主站蜘蛛池模板: 亚洲五月午夜免费在线视频| 中文精品人人永久免费| 免费无码A片一区二三区| 亚洲国产理论片在线播放| 57pao国产成视频免费播放| 亚洲国产国产综合一区首页| 日韩成人免费视频| 亚洲情a成黄在线观看动漫尤物| 国内永久免费crm系统z在线| 国产成人无码综合亚洲日韩| 免费一级不卡毛片| 亚洲最大的成网4438| 无人在线直播免费观看| 亚洲中文字幕一二三四区| 日韩伦理片电影在线免费观看| 男女猛烈xx00免费视频试看| 亚洲人成色7777在线观看不卡| 丁香花在线观看免费观看图片| 亚洲高清国产AV拍精品青青草原 | 精品亚洲成a人片在线观看| 91久久精品国产免费一区| 亚洲国产成人在线视频| 国产美女被遭强高潮免费网站| 最好2018中文免费视频| 久久亚洲精品成人777大小说| 无码人妻一区二区三区免费手机| 亚洲日本va一区二区三区| 亚洲成a人片在线观看老师| 在线免费视频你懂的| 亚洲日韩中文字幕天堂不卡 | 国产99精品一区二区三区免费| 亚洲熟妇无码八AV在线播放| av无码免费一区二区三区| 亚洲av永久无码| 久久国产亚洲电影天堂| 久久久久久国产精品免费免费| gogo免费在线观看| 亚洲校园春色另类激情| 亚洲天堂免费在线视频| 男女做羞羞的事视频免费观看无遮挡| 无码免费又爽又高潮喷水的视频|