jasmine214--love

          只有當你的內心總是充滿快樂、美好的愿望和寧靜時,你才能擁有強壯的體魄和明朗、快樂或者寧靜的面容。
          posts - 731, comments - 60, trackbacks - 0, articles - 0

          Javascript精粹---對象(檢索/原型/枚舉屬性)

          Posted on 2010-06-27 17:46 幻海藍夢 閱讀(1986) 評論(0)  編輯  收藏 所屬分類: JS
          原文:http://pouyang.javaeye.com/blog/576127
          對于丑陋的事物,愛會閉目無視


          JavaScript中的對象是可變的鍵控集合(keyed collections)
          對象是屬性的容器,其中每個屬性都擁有名字和值。屬性的名字可以是
          包括字符串在內的任意字符串,屬性值可以是除undefined值之外的任何值

          JavaScript中的對象是無類別的,它對新屬性的名字和值沒有約束。對象適合
          用于收集和管理數據。對象可以包含其他對象,所以它們可以容易地表示成
          樹形或圖形結構(注意:樹和圖強大的數據結構)

          JavaScript包括一個原型鏈特性,允許對象繼承另一對象的屬性。正確地使用它能
          減少對象初始化的時間和內存消耗


          對象檢索

          Js代碼 復制代碼
          1. var ?empty_object?=?{}; ??
          2. var ?stooge?=?{ ??
          3. ???? "first-name" : "Ouyang" , ??
          4. ???? "last-name" : "ping" , ??
          5. ???? "yyl" : "yyl" ??
          6. } ??
          7. alert(stooge[ "first-name" ]);? //Ouyang ??
          8. alert(stooge.first-name); //NaN ??
          9. alert(stooge.yyl) //yyl ??
          10. alert(stooge.name); //undefined ??


          ||運算符可以用來填充默認值
          Js代碼 復制代碼
          1. var?middle?=?stooge["middle-name"]?||"none"; ??
          2. ??
          3. flight.equipment?//?undefined ??
          4. flight.equipment.model?//?throw?"TypeError" ??
          5. flight.equipment?&&?flight.equipment.model?//undefined??


          原型

          返回對象類型原型的引用。

          objectName.prototype

          objectName 參數是對象的名稱
          原型連接在更新時是不起作用的,當我們對某個對象做出改變時,不會觸及到該對象
          的原型,原型連接只有在檢索值的時候才被用到,如果我們嘗試去獲取對象的某個屬性,且
          該對象沒有此屬性,那么JavaScript會試著從原型對象中獲取屬性值。如果那個原型對象也
          沒有該屬性,那么再從它的原型中尋找,依次類推,直到該過程最后到達
          終點Object.prototype,如果想要的屬性完全不存在于原型鏈中,那么結果就是
          undefied值,這個過程成為委托。

          Js代碼 復制代碼
          1. function?TestObjectA()? ??
          2. {? ??
          3. ????this.MethodA?=?function()? ??
          4. ????{? ??
          5. ???????alert('TestObjectA.MethodA()');? ??
          6. ????}? ??
          7. }? ??
          8. ??
          9. function?TestObjectB()? ??
          10. {? ??
          11. ????this.bb?=?'ccc'; ??
          12. ????this.MethodB?=?function()? ??
          13. ????{? ??
          14. ???????alert('TestObjectB.MethodB()');? ??
          15. ????}? ??
          16. }? ??
          17. ??
          18. TestObjectB.prototype?=?new?TestObjectA();?//TestObjectB繼承了?TestObjectA的方法 ??
          19. ??
          20. TestObjectB.prototype.bb?=?'aaaaa';?//添加屬性 ??
          21. var?temp ??
          22. var?b?=?new?TestObjectB(); ??
          23. for?(temp?in?b)?{ ??
          24. ??alert(temp);?//?MethodA??bb?MehtedB ??
          25. } ??
          26. var?kk?=?new?TestObjectB(); ??
          27. //刪除,但原型鏈中的沒有刪除 ??
          28. alert(kk.bb);?//?ccc ??
          29. delete?kk.bb; ??
          30. alert(kk.bb);?//?aaaa ??
          31. ??
          32. alert(kk.MethodA());?//TestObjectA.MethodA()??


          此處轉載 http://fengsky491.javaeye.com/blog/228583 謝謝 fengsky491
          JScript里的prototype,為什么我們說它和prototype pattern里的prototype不一樣呢?! 這個不是我說就說出來的,也不是我吹出來的,看看這個示例,你就能大概糊涂:?
          Js代碼 復制代碼
          1. ?<script?language="javascript"> ??
          2. function?RP()? ??
          3. {? ??
          4. ????RP.PropertyA?=?1;? ??
          5. ????RP.MethodA?=?function()? ??
          6. ????{? ??
          7. ?????????alert("RP.MethodA?");? ??
          8. ????};? ??
          9. ???? ??
          10. ????this.PropertyA?=?100;? ??
          11. ????this.MethodA?=?function()? ??
          12. ????{? ??
          13. ?????????alert("this.MethodA");? ??
          14. ????};? ??
          15. }? ??
          16. ??
          17. RP.prototype.PropertyA?=?10;? ??
          18. RP.prototype.MethodA?=?function()? ??
          19. {? ??
          20. ????alert("RP.prototype.MethodA");? ??
          21. };? ??
          22. </script>???
          ?? 不要著急,還沒有開始做示例,只是給出了我們用來演示的一個類。RP是什么?rpwt嗎?當然不是了,RP是ResearchPrototype了。好了不廢話了,看示例及結果分析。??
          Js代碼 復制代碼
          1. <script?language="javascript">? ??
          2. rp?=?new?RP();? ??
          3. alert(RP.PropertyA);? ??
          4. RP.MethodA();? ??
          5. alert(rp.PropertyA);? ??
          6. rp.MethodA();? ??
          7. </script>? ??
          8. ????運行結果閃亮登場:? ??
          9. ???1? ??
          10. ???RP.MethodA? ??
          11. ???100? ??
          12. ???this.MethodA? ??
          13. ????這個%$@#^$%&^...,不要著急,繼續看哦!???


          Js代碼 復制代碼
          1. <script?language="javascript">? ??
          2. rp?=?new?RP();? ??
          3. delete?RP.PropertyA;? ??
          4. alert(RP.PropertyA);? ??
          5. delete?RP.MethodA;? ??
          6. RP.MethodA();? ??
          7. delete?rp.PropertyA;? ??
          8. alert(rp.PropertyA);? ??
          9. delete?rp.MethodA;? ??
          10. rp.MethodA();? ??
          11. </script>? ??
          12. ????運行結果再次登場:? ??
          13. ???undefined? ??
          14. ???A?Runtime?Error?has?occurred.? ??
          15. ???Do?you?wish?to?Debug?? ??
          16. ???Line:?32? ??
          17. ???Error:?Object?doesn't?support?this?property?or?method? ??
          18. ???10? ??
          19. ???RP.prototype.MethodA???

          ??? 好玩吧,看出來什么名堂了嗎?這里的RP.PropertyA和RP.MethodA只是用來做參照的,可是怎么把this.PropertyA和this.MethodA都delete了,還能出來結果,而且還是prototype導入的屬性和方法呢?

          ??? 這就是JScript的prototype和prototype pattern中prototype最大的不同了,JScript中的這個所謂的prototype屬性其實是個語言本身支持的特性,這里沒有發生任何的copy,不管shallow還是deep的。對于JScript的解釋引擎,它在處理"."或"[keyName]"引用的對象的屬性和方法時,先在對象本身的實例(this)中查找,如果找到就返回或執行。如果沒有查找到,就查找對象的prototype(this.constructor.prototype)里是否定義了被查找的對象和方法,如果找到就返回或執行,如果沒有查找到,就返回undefined(對于屬性)或runtime error(對于方法)。

          ??? 正因為prototype導入類實例的屬性或方法是動態查找的,所以我們才能對系統內部對象添加prototype屬性和方法,比如給String對象添加trim方法:

          Js代碼 復制代碼
          1. <script?lanuage="javascript">? ??
          2. String.prototype.trim()? ??
          3. {? ??
          4. ????return?this.replace(/(^\s+)|(\s+$)/g,?"");? ??
          5. }? ??
          6. </scritp>???
          ?
          ? 顯然JScript中的這種用法也是prototype pattern中的prototype不能解釋和支持的。

          ??? 這下對于JScript OOP中原型繼承法的理解因該沒有任何的障礙了吧?同時也應該明白為什么原型繼承法有那么大的天生缺陷了吧?當然如果有任何問題,歡迎繼續討論。



          反射

          檢查對象并確定對象有什么屬性是很容易的事情,只要試著去檢索
          該屬性并驗證取得的值,typeof操作符對確定屬性的類型很有幫助。


          Js代碼 復制代碼
          1. typeof?flight.number??


          另一個方法是使用hasOwnProperty方法,如果對象擁有獨有的屬性,它將返回true.
          hasOwnProperty方法不會檢查原型連


          Js代碼 復制代碼
          1. flight.hasOwnProperty('nubmer');??





          枚舉(對象屬性)
          for in 語句可用來遍歷一個對象中的所有屬性名,該枚舉過程將會列出所有的屬性
          包括函數和你可能不關心的原型中的屬性,所以有必要過濾掉那些你不想要的值。最為常用
          的過濾器是hasOwnProperty方法,以及使用typeof來排除函數:

          Js代碼 復制代碼
          1. var?name; ??
          2. for?(name?in?another_stooge)?{ ??
          3. ????if?(typeof?another_stooge[name]?!=?'function')?{ ??
          4. ????????document.writeln(name+':'+another_stooge[name]); ??
          5. ????} ??
          6. }??


          屬性名出現的順序是不確定的,因此要對任何可能出現的順序有所準備,如果你想要確保屬性以特定的順序出現,
          最好的辦法就是完全避免使用 for in語句,而是創建一個數組,在其中以正確的順序包含屬性名
          Js代碼 復制代碼
          1. var?i?; ??
          2. var?properties?=?[ ??
          3. ????'first-name', ??
          4. ????'middle-name', ??
          5. ????'last-name', ??
          6. ????'profession'??
          7. ]; ??
          8. for?(i?=?0?;?i?<?properties.length;?i?+=?1)?{ ??
          9. ????document.writeln(properties[i]+':'+another_stooge[properties[i]]); ??
          10. }??
          通過使用for而不是for in ,可以得到我們想要的屬性,而不用擔心可能發掘出原型鏈中的屬性,并且我們按
          正確的順序取得了它們的值。
          主站蜘蛛池模板: 星子县| 梅州市| 高阳县| 北海市| 榆林市| 土默特左旗| 敦化市| 龙门县| 弥渡县| 军事| 高平市| 图木舒克市| 汝城县| 临潭县| 青海省| 修武县| 三门峡市| 沛县| 专栏| 黄梅县| 隆化县| 伊吾县| 平江县| 隆林| 咸宁市| 涞源县| 全椒县| 三台县| 台北县| 彰武县| 登封市| 阿瓦提县| 巩义市| 东兴市| 宁南县| 体育| 鲁甸县| 大竹县| 南江县| 监利县| 遂昌县|