syuko——驿路梨花

武汉人勇闯天下
爽气西来,云雾扫开天地撼;大江东去,波涛洗净古今愁。
posts - 18, comments - 148, trackbacks - 11, articles - 1
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

JavaScript基础之对象

Posted on 2008-03-05 14:29 syuko——驿路梨花 阅读(3292) 评论(51)  编辑 收藏 所属分类: 技术随笔

JavaScript基础之对象

    从2004年下半年开始学习Web编程至今3年有余。从HTML,asp开始到现在的VS2008一路学过来,其中学的最多的还是服务器端编程,对客户端编程的学习还是不成系统。虽然在很多个系统里面应用过脚本,有些还起到了比较重要的作用。但一直是只知其然不知其所以然,用的是小心翼翼。现在脚本编程从以前的"雕虫小技"变成了一个Web开发不可或缺的元素,其地位大大提高了,特别是Ajax兴起之后它更是"炙手可热"了。鉴于此种情况及自己对脚本编程的热爱,于是就系统地学习一下脚本。

    学习是理解和记忆的过程。在理解和记忆的过程中必不可少地就需要一些辅助的记录,于是我就将自己的学习记录写成随笔。一来是帮助自己理解和记忆,二来也给其它热爱脚本的同志一些参考。

 1 JavaScript对象

    ECMA-262将对象(object)定义为"属性的无序集合,每个属性存放一个原始值、对象或函数"(unordered collection of properties each of which contains a primitive value, object, or function)。这意味着对象是无特定顺序的值的数组。在ECMAScript中,对象由特性(Attribute)构成,特性可以是原始值,也可以是引用值。如果特性存放的是函数,它将被看作对象的方法(Method),否则该特性被看作属性(Property)。

2 对象的废除

    ECMAScript有无用存储单元收集程序(就像C#的垃圾收集器)意味着不必专门销毁对象来释放内存。当再没有对对象的引用时,该对象就被废除了。运行无用存储单元收集程序时,所有废除的对象都会被销毁。每当函数执行完它的代码,无用存储单元收集程序都会运行,释放所有的局部变量,还有在一些其它不可预知的情况下,无用存储单元收集程序也会运行。
   
把对象的所有引用都设置为null,可以强制性的废除对象。例如:

    Var oObject=new Object();

    // 程序逻辑

    oObject=null;

    当变量oObject设置为null后,对第一个创建的对象的引用就不存在了。这意味着下次运行无用存储单元收集程序时,该对象将被销毁。 
    
每用完一个对象后,就将其废除,来释放内存,这是个好习惯。这样还确保不再使用已经不能访问的对象,从而防止程序设计错误的出现。此外,旧的浏览器(如IE)没有完全的无用存储单元收集程序,所以卸载页面时,对象可能不能被正确地销毁。以前IE6就有这样的诟病,当页面被关闭后对象还是没有被释放,所以总是会导致内存溢出的错误。废除对象和它所有的特性是确保内存正确使用的最好方法。

3 对象的类型

    JavaScript中对象分为:本地对象(native object)、内置对象(built-in object)、宿主对象(host object)。其中本地对象和宿主对象大家一般用的比较多,比较熟。这里我就重点说明一下内置对象。 
    
ECMA-262把内置对象定义为"由ECMAScript实现提供的、独立于宿主环境的所有对象,在ECMAScript程序开始执行时出现"(any object supplied by an ECMAScript implementation, independent of the host environment, which is present at the start of the execution of an ECMAScript program.)。这意味着开发者不必明确实例化内置对象,它已经被实例化了。但ECMAScript只定义了两个内置对象:

3.1 Math对象

    Math对象就是解决数学问题的所有公式。这个在各种编程语言中都有类似的实现,就不做介绍了。

3.2 Global对象

    园子里很多搞ASP.net的,相信大家对其中的Global.asax非常熟悉了。但这个对象在ECMAScript中却比较特殊。因为它实际上根本就不存在。如果尝试编写下面的代码去实例化它,将得到错误: 
    
Var _global=new Global(); 
    
错误消息显示Global不是对象,但上文却说Global是一个内置对象,这不就自相矛盾了吗?不矛盾。这里需要理解的主要概念是,在ECMAScript中,不存在独立的函数,所有的函数都必须是某个对象的方法。ECMAScript中常用的函数例如isNaN()、isFinite()等,看起来都像独立的函数。实际上,它们都是Global对象的方法。而且Global对象的方法还不止这些。

4 定义类或对象

    虽然ECMAScript越来越正规化了,但创建对象的方法却被置之不理。在高级的编程语言(如C#)中,创建对象的方法被明确的定义了。所以不会有太大的分歧。但在脚本语言中创建对象的方法就是多种多样了。

4.1 工厂方式

由于对象的属性可在对象创建后动态定义,所以许多开发者都在初次引入JavaScript时编写类似下面的代码: 
    
Var oCar=new Object(); 
    
oCar.color="red"; 
    
oCar.doors=4; 
    
oCar.mpg=23; 
    
oCar.showColor=function(){alert(this.color);}; 
    在这段代码中,创建对象car。然后给它设置几个属性:它的颜色是红色,有四个门,每加仑油23英里。最后一个属性是指向函数的指针,意味着该属性其实是个方法。执行这段代码后,就可以使用对象car了。可是要创建多个car实例就麻烦了。 
    
要解决此问题,开发者可以创建并返回特定类型的对象的工厂函数。例如,函数CreateCar()可用于封装前面列出的创建car对象的操作: 
    
Function createCar() 
    

        
Var oTempCar=new Object(); 
        
oTempCar.color="red"; 
        
oTempCar.doors=4; 
        
oTempCar.mpg=23; 
        
oTempCar.showColor=function(){alert(this.color)};
    
        
return oTempCar; 
    


    Var oCar1=createCar(); 
    
Var oCar2=createCar();

    这里,前面的所有代码都包含在createCar()函数中,此外还有一行额外的代码,返回Car对象作为函数值。调用此函数时,将创建新对象,并赋予它所有必要的属性,复制出一个前面说明的car对象。使用该方法,可以容易地创建car对象的两个版本,他们的属性完全一样。当然,还可以修改creatCar()函数,给它传递各个属性的默认值,而不是赋予属性默认值: 
    
Function createCar(sColor,iDoors,iMpg) 
    

        
Var oTempCar=new Object(); 
        
oTempCar.color= sColor; 
        
oTempCar.doors= iDoors; 
        
oTempCar.mpg= iMpg; 
        
oTempCar.showColor=function(){alert(this.color)};

        return oTempCar; 
    

    
    
Var oCar1=createCar("red",4,23); 
    
Var oCar2=createCar("blue",2,26); 
    
oCar1.showColor();            // 输出"red" 
    
oCar2.showColor();            // 输出"blue"

    给createCar()函数加上参数,即可为要创建的car对象的color、doors和mpg属性赋值。使这两个对象具有相同的属性,却有不同的属性值。但这里有个问题:每次调用函数createCar(),都要创建新函数showColor(),意味着每个对象都有自己的showColor()版本。事实上,每个对象用的都是同一段代码。这样的定义方法还有一个如下的变形:
    Function Car(sColor,iDoors,iMpg) 
    

        
this.color= sColor; 
        
this.doors= iDoors; 
        
this.mpg= iMpg; 
        
this.showColor=function(){alert(this.color)}; 
    
}

    Var oCar1=new Car("red",4,23); 
    
Var oCar2=new Car("blue",2,26);

    oCar1.showColor();            // 输出"red" 
    
oCar2.showColor();            // 输出"blue" 
    这个方法和上一个方法有个一样的缺陷:重复的创建了showColor()函数。为了解决这个缺陷我们可以用下面的方法。

4.2 原型方式

    该方法利用了对象的Prototype属性。用空构造函数来设置类名,然后所有的属性和方法都被直接赋予prototype属性: 
    
Function Car() 
    
{} 

    
Car.prototype.color="red"; 
    
Car.prototype.doors=4;
    
Car.prototype.mpg=23; 
    
Car.prototype.showColor=function(){alert(this.color)};

     Var oCar1=new Car(); 
    
Var oCar2=new Car();

    使用这个方法可以解决重复创建showColor()函数,但又会有新的问题,考虑下面的例子: 

    
Function Car() 
    
{} 

    
Car.prototype.color="red"; 
    
Car.prototype.doors=4; 
    
Car.prototype.mpg=23; 
    
Car.prototype.drivers=new Array("Mike","Sue"); 
    
Car.prototype.showColor=function(){alert(this.color)};

     Var oCar1=new Car(); 
    
Var oCar2=new Car();

    oCar1.drivers.push("Matt"); 

    
alert(oCar1.drivers);        // 输出"Mike,Sue,Matt" 
    
alert(oCar2.drivers);        // 输出"Mike,Sue,Matt"

    这里,属性drivers是指向Array对象的指针。改变指针指向的内容,所有的实例都会改变。看来这种方法也不可取

    4.3 混合方式

    这种方式就是用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法)。结果所有的函数只创建一次,而每个对象都具有自己的对象属性实例。 
    
Function Car(sColor,iDoors,iMpg) 
    

        
this.color= sColor; 
        
this.doors= iDoors;

this.mpg= iMpg;
Car.drivers=new Array("Mike","Sue");
}

Car.prototype.showColor=function(){alert(this.color)};

Var oCar1=new Car("red",4,23);
Var oCar2=new Car("blue",3,25);

oCar1.drivers.push("Matt");

alert(oCar1.drivers);        // 输出"Mike,Sue,Matt"
alert(oCar2.drivers);        // 输出"Mike,Sue"

这种方式是ECMAScript主要采用的方式,它具有其他方式的特性,却没有它们的缺陷。在实际编程中应用的也是最多了。 
另外还有JSON创建方式。其创建的方式如下:

var Car =

    
color: "red", 
    
doors: 4, 
    
mpg: 23, 
    drivers: [{name: "Mike", age: 20, Married: false}, {name: "Sue", age: 30, Marred: true}],
    showColor: function() {alert(this.color)}
};
这种创建对象的方式也比较优雅。可作为Ajax返回的文本,然后用eval()函数将其还原成一个对象。著名的脚本框架JQuery就有专门接收返回文本为JSON对象的异步方法。


Feedback

#1楼    回复  引用  查看    

2008-03-05 15:21 by 秋千      
不错

#2楼    回复  引用  查看    

2008-03-05 15:41 by 老钱      
看得有点晕.基本懂了

#3楼    回复  引用  查看    

2008-03-05 15:41 by peace      
顶下

#4楼    回复  引用    

2008-03-05 15:41 by 123dasdas [未注册用户]
垃圾

#5楼    回复  引用    

2008-03-05 16:06 by -..- [未注册用户]
看看楼上的言论。。我顶楼主

#6楼    回复  引用  查看    

2008-03-05 16:07 by BlueMountain      
学习 多谢

#7楼 [楼主]   回复  引用  查看    

2008-03-05 16:13 by 驿路梨花      
@秋千
@peace
@-..-
@BlueMountain
谢谢各位的支持,只有大家支持我,我才能继续写下去。
下一篇我准备写继承相关的东西,希望大家能喜欢。

#8楼 [楼主]   回复  引用  查看    

2008-03-05 16:14 by 驿路梨花      
@老钱
看的有点晕说明我把简单的问题写的太晦涩了,下一篇注意这个问题,尽量不把简单的问题复杂化。

#9楼 [楼主]   回复  引用  查看    

2008-03-05 16:16 by 驿路梨花      
@123dasdas
博客园有个非常好的讨论环境,这个环境需要大家共同去维持。

#10楼    回复  引用    

2008-03-05 16:49 by www.mmic.net.cn [未注册用户]
有必要放到首到吗?

#11楼    回复  引用  查看    

2008-03-05 17:24 by gjcn      
@www.mmic.net.cn
请问什么东西能放到首页,这个标准我一直都没有把握好。谁知道能否告诉我

#12楼    回复  引用  查看    

2008-03-05 17:52 by 兴百放      
这个目录好像一本书上的目录
《JavaScript 高级程序设计》

#13楼    回复  引用    

2008-03-05 17:53 by sg [未注册用户]
这些东西有必要发到首页吗?
不懂的那些家伙,你们看过书没有?
07年买过书看没有?
知道有一本书叫<javascript高级程序设计>吗?
博主上面有些例子就是从那里拿来的!

#14楼    回复  引用    

2008-03-05 17:55 by sg [未注册用户]
@gjcn

你没学好,没认真学,我们不怪你。
自己还是拿上网看博客的时间去看一会书,真的,看过之后,你会发觉上面写的全是废话!

#15楼    回复  引用  查看    

2008-03-05 18:05 by BlueMountain      
楼上的真牛啊 unix代码都开放了 那么问问题的人和回答问题的人是不是都该挨骂 我看你的评论才是废话 连个真名字都不敢用

强烈盼望lz贴出第二章 关于继承的东西

#16楼    回复  引用  查看    

2008-03-05 19:16 by 杨正祎      
原创的、经过自己精心写作的,对多数人都有帮助的,就可以放在首页。
如果这篇是原创的,我认为完全,而且应该放在首页。

#17楼    回复  引用    

2008-03-05 20:14 by sg [未注册用户]
@BlueMountain
我的意思书面上有的,就不应该这样粘出来了!还浪费大家的获取信息资源的空间
自己多花点心思理想再分享,绝对赞同,就像@杨正祎同学一样,书上都有的东西,不值得你在这里叫好,那只能证明你够懒

#18楼    回复  引用  查看    

2008-03-05 20:46 by 生鱼片      
我觉得博主的这篇文章无论是质量上还是内容都不错

#19楼    回复  引用    

2008-03-05 21:28 by zzz [未注册用户]
一切尽在《JavaScript 高级程序设计》

嗯,不说

#20楼    回复  引用  查看    

2008-03-05 22:56 by BlueMountain      
#17楼 221.217.118.* 回复 引用 查看
2008-03-05 20:14 by sg [未注册用户]
@BlueMountain
我的意思书面上有的,就不应该这样粘出来了!还浪费大家的获取信息资源的空间
自己多花点心思理想再分享,绝对赞同,就像@杨正祎同学一样,书上都有的东西,不值得你在这里叫好,那只能证明你够懒
----------如果我言语过激,在这里向你道歉。

至于《JavaScript 高级程序设计》这本书,我刚刚下了订单,不敢妄加评论,其实市面上很多js学习的书。楼主在这里做了概括,我觉得挺好的。

我现在工作的系统中用的js不少,但是写得都很不规范,我看到lz这边文章,才知道原来原来那些js有不少问题。

#21楼    回复  引用  查看    

2008-03-05 23:30 by 李华星      
LZ肯定已经看过这本书, 才整理出来的, 当然可以放在首页, 我想问一下, 有哪位高人能写出连书上的没有的文章来啊

#22楼    回复  引用  查看    

2008-03-06 00:51 by 梁逸晨      
我认为后面这些回复都已经脱离了主题

#23楼    回复  引用  查看    

2008-03-06 01:44 by nfa2dfa      
我不怕得罪人。
我认为这篇随笔的程度不适合放在首页上。
而且我认为杨正祎的很多随笔除了包装漂亮以外,内容陈旧,也不适合放在首页上。
事实上,能达到绝对原创且有深度的随笔cnblogs少之又少。不过如果抱着这种心态去看csdn的话,恐怕是要哭出来了。
至于www.asp.net或是其他国外站点也不是天天都有新鲜文的。
但是我觉得大家愿意分享知识的热情是值得尊重的,大家严肃的学习态度是值得尊重的,大家付出的劳动是值得尊重的。
即便是整理或转载,对博主也是有意义的,或梳理知识,或方便查找。
即便是放到首页被说两句,对博主也是有意义的,认识不足,锤炼心态。

不过废话了半天,总结性的话是
'''
原创的、经过自己精心写作的,对多数人都有帮助的,就可以放在首页。
如果这篇是原创的,我认为完全,而且应该放在首页。
'''
转载自
杨正祎

#24楼 [楼主]   回复  引用  查看    

2008-03-06 08:13 by 驿路梨花      
@兴百放
@sg
@zzz
如各位所说,这篇帖子里的内容确实很多是来自《JavaScript高级程序设计》(Professional JavaScript for Web Developers),但其内容是经过自己加工、理解过的。而且在这篇帖子的前面我也说过“学习是理解和记忆的过程。在理解和记忆的过程中必不可少地就需要一些辅助的记录,于是我就将自己的学习记录写成随笔。一来是帮助自己理解和记忆,二来也给其它热爱脚本的同志一些参考。”,既然是学习肯定是由有所依托的,当然学习刚开始写出来的东西和书本上还是有很大的相似性的。这样是因为刚学习把握不好尺度,抛开书本只写自己的理解我担心写不好而误人误己。所以刚开始就借鉴一下一本收受到好评的书籍里面的内容大家更容易信服。而且整个"JavaScript基础"不止这一篇文章,在后续的文章里我会慢慢地加入自己的东西。如果大家都认为这样的文章不适合放在首页我会乐意接受大家的意见将其移走。

#25楼 [楼主]   回复  引用  查看    

2008-03-06 08:26 by 驿路梨花      
@sg
--引用--------------------------------------------------
07年买过书看没有?
知道有一本书叫《javascript高级程序设计》吗?

--------------------------------------------------------
纠正一个小问题:《javascript高级程序设计》的英文版是05年出的,中文译本是06年出的。

#26楼 [楼主]   回复  引用  查看    

2008-03-06 08:29 by 驿路梨花      
@BlueMountain
第二篇继承我会努力写好的。:)

#27楼 [楼主]   回复  引用  查看    

2008-03-06 08:31 by 驿路梨花      
@杨正祎
非常喜欢你在Web标准方面研究的东西:)

#28楼    回复  引用  查看    

2008-03-06 09:26 by 韩现龙      
无论批评的还是鼓励的言论,我都希望我的小浩子能够坚持下去。
神在注视着你(我是无神论者)。

#29楼    回复  引用  查看    

2008-03-06 09:32 by Rivers Zhao      
这是一篇好文
如果是原创且对大家有帮助的,我们都应该支持!

#30楼    回复  引用  查看    

2008-03-06 09:47 by 夏保华      
只要有人愿意看的东西,放在首页就是有意义,
什么是有意义:
"有人愿意看就是有意义,有意义就是有人愿意看"
东西写的再好,再深奥,但所写的技术不是网友喜欢看的,放在首页也是没人看的,园友也知道好多有些技术深层的文章放在首页,几乎看不到园友浏览,能不能放在首页不是一个人或几个人嘴里说定的,是园友和其他热爱IT行业网友...或看或学习的人决定的,
补充一下:那些牛X的人大可不需要看,看了去发一些批判坏了心情也浪费了时间.!

#31楼    回复  引用  查看    

2008-03-06 10:19 by Annie      
对象的类型
这部分,楼主能不能再讲的详细些?谢谢!

#32楼 [楼主]   回复  引用  查看    

2008-03-06 10:52 by 驿路梨花      
@Annie
这个问题就是众口难调了。简单了大家说不应该往上放,粗略了难免遗漏呀。下次我尽量兼顾吧。

#33楼 [楼主]   回复  引用  查看    

2008-03-06 11:19 by 驿路梨花      
@Annie
本地对象就是Function、Array、String等之类的对象,共15个。
比如常用的Array类:
var myArray=new Array();
声明的时候可以不声明数组的长度,这和一些高级编程语言有些不同。然后可以采用下面的方式赋值:
myArray[0]="1";
myArray[1]="2";
......

myArray.push("1"); // 添加
myArray.pop(); // 压出一个
就像栈一样,配合数组的shift()和unshift()方法还可以达到队列的效果。
数组还有其它很多的方法,这里就不一一列举了。

宿主对象(host object)则是指那些实现了ECMAScript-262规范的浏览器提供的对象。比如:DOM对象,浏览器对象等。这些对象是由那些浏览器厂商提供的。

#34楼    回复  引用  查看    

2008-03-06 12:09 by hoodlum1980      
看了上面的回复。
第一:我有一个感觉,《JavaScript高级程序设计》这本书我应该买来看看。
第二,大家对上首页的文章的要求很高。个人感觉也是如此,迄今我只往首页上放过大概3篇技术文章。

#35楼    回复  引用  查看    

2008-03-06 12:19 by hoodlum1980      
个人感觉,
1.如果文章内容是你读书或者收集的知识点的整理笔记以及你的理解和消化性观点(没有任何你自己提出的原创思想或者产品或者demo),也就是说,完全没有自己的东西在里面,并且会在该领域内中等水平的人所大概了解,那么这类文章不适合放首页上。
2。例外情况是,如果这个领域尚属空白,知者甚少,那么作为介绍性质的文章,总结现有的技术和知识点,作为一种整理也是非常有价值的(因为这也节省了别人的时间,而不是“懒”),在论文里面有这么一类论文叫做综述。这样的文章可以发到首页上,并且一定要注明出处以作为对原作者的尊重。
3.发布到首页前,应该思考一下,这篇文章对自己的价值,以及对读者可能产生的价值,较大,则发。对自己价值较大,但如果对读者价值较小,不发。

#36楼    回复  引用    

2008-03-06 12:42 by it_lwj [未注册用户]
楼住你写的东西好像是跟JavaScript高级程序设计里一模一样的

#37楼    回复  引用  查看    

2008-03-06 14:07 by Annie      
谢谢楼主!

#38楼    回复  引用    

2008-03-06 14:39 by 念时11 [未注册用户]
何苦要在是否该放到首页上这些无谓的问题上争论呢,楼主把文章贴出来不就是想把自己的一点心得与大家分享讨论吗 真不知某些人在想什么?

#39楼    回复  引用  查看    

2008-03-06 18:06 by 破曉之陽      
@sg
并不是所有的人 都有那么多钱买书。。
如果你能 把《JavaScript高级程序设计》 正本的书发布在网上给给人看。别加上你的理解,就像CSDN上扬。不过它上面都是一部分。 我相信点击率也会很高的。

再说了。如果 不适合放首页,会有人处理的。没必要 ,在这里说些什么的啊。


谢谢楼主分享。

#40楼    回复  引用  查看    

2008-03-07 00:25 by 狼Robot      
浪费了我几分钟的时间看一些没有意义的评论...

#41楼    回复  引用  查看    

2008-03-11 08:21 by 朱保旭      
真服了,一篇文章也能引发血案。只是一篇学习的文章,大家至于如此这般吗?

#42楼    回复  引用  查看    

2008-03-14 15:23 by 天生俪姿      
收藏了先。
谢谢楼主

#43楼    回复  引用  查看    

2008-03-17 11:12 by 天生俪姿      
血案?
何来的血案?

子民。 有意思。

#44楼    回复  引用    

2008-03-18 16:25 by TommyKnocker [未注册用户]
w3schools还介绍了一种创建对象方法的方式

function person(firstname,lastname,age,eyecolor)
{
this.firstname=firstname;
this.lastname=lastname;
this.age=age;
this.eyecolor=eyecolor;

this.newlastname=newlastname;
}

function newlastname(new_lastname)
{
this.lastname=new_lastname;
}

#45楼    回复  引用  查看    

2008-03-18 16:51 by 杜军      
《JavaScript高级程序设计》这本书没看过,不过楼主把书上精彩的部分拿出来让大家学习,就是好人!

#46楼    回复  引用    

2008-03-18 22:42 by 酷勤网 [未注册用户]
看到那么评论的数量,以为是讨论javascript,原来是讨论要不要放首页,汗。博客园的文章我都是通过rss订阅的,多几篇在首页根本不会影响阅读的,不像论坛刷帖。

#47楼    回复  引用    

2008-03-20 18:19 by Jot [未注册用户]
文章不错!学到不少。
至于看书还是看博客,我都觉得无所谓了。

#48楼    回复  引用  查看    

2008-03-25 10:04 by BAsil      
原文
Function Car(sColor,iDoors,iMpg)
{
this.color= sColor;
this.doors= iDoors;

this.mpg= iMpg;
Car.drivers=new Array("Mike","Sue");
}
有误,Car.drivers应为this.drivers.
另外Function和Var不应该大写阿!

#49楼    回复  引用    

2008-06-26 17:50 by war3 [未注册用户]
我觉着能写出来,并让大家看了有所收获就很好。支持楼主

#50楼    回复  引用    

2008-08-18 14:31 by Yvon [未注册用户]
谢谢楼主的分享,正在找这方面的资料

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
博客园首页

新闻频道

社区

小组

博问

网摘

闪存

  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-03-05 14:46 编辑过
成果网帮您增加网站收入


相关链接: