jasmine214--love

只有当你的内心总是充满快乐、美好的愿望和宁静时,你才能拥有强壮的体魄和明朗、快乐或者宁静的面容。
posts - 731, comments - 60, trackbacks - 0, articles - 0

Javascript精粹---对象(检索/原型/枚举属性)

Posted on 2010-06-27 17:46 幻海蓝梦 阅读(1981) 评论(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 ,可以得到我们想要的属性,而不用担心可能发掘出原型链中的属性,并且我们按
正确的顺序取得了它们的值。

只有注册用户登录后才能发表评论。


网站导航: