我试过很多次,最后得到一个结论就是让事情变得简单总是好的。如果你正在一个团体内工作的话,如果技术领导觉得有必要的话,应该将前面的内容写入编码规约或者是指导手册里面。还有需要知道这些区别以及技巧的第二个原因是,浏览器会在内部使用一些规则,所以有必要理解这些以便能在调试程序的时候节省时间和精力。尤其是,我发现在知道那些表面相似点只限于表面的情况下,对知道在哪些地方代码不会像Java一样运行很有用。所以继续读吧,然后看看JavaScript的对象究竟是怎么工作的,它们是怎样由域和函数组成,JavaScript的函数又究竟能干什么。
B2 JavaScript的对象
JavaScript不需要使用对象会甚至函数。它可以以流的形式写一个程序,然后通过编译器编译代码来执行。但是当程序比较大的时候,函数和对象就非常有用了,它可以让代码变得更条理一些,我们推荐两个都要用。
最简单的创建对象的方法就是通过内置的Object对象的构造函数来得到,如下:
var myObject=new Object();
我们将在后面看到其他的方法,学习new这个关键字到底是干什么的,在B2.2,我们的myObject对象被初始化为“empty”,也就是说它没有属性和方法,添加属性和方法是一件很简单的事情,下面就来看一下。
B2.1 创建ad hoc对象
像我们在前面提到过的一样,JavaScript的对象本质上就是一个通过名字来标示的域和方法的关联的数组。有点类似于C语言的标识符让C程序员觉得熟悉,但是底层的实现是通过其他方法实现的。我们可以创建通过添加新变量和函数来实现一个复杂的对象,这有两种方法第一种就是用JavaScript来创建,第二种使用一种叫JSON的特殊标记来实现。下面我们先从普通的创建方法入手来看一下。
使用JavaScript声明
在一段复杂的代码当中,我们有可能想给一个对象的某个属性赋值,JavaScript的对象属性可以读写,并且可以用“=”来赋值。下面给我们刚才的对象赋值:
myObject.shoeSize="12";
在结构化的面向对象语言中,我们需要生命一个具有shoeSize属性的类,否则将会有编译错误,但实在JavaScript中不是这样的,实际上,因为与数组类似这个特征,我们就可以用访问数组的方法来访问这个属性:
myObject['shoeSize']="12";
这种写法对于普通的应用来讲也许笨拙了一些,但是也有它的优点,因为数组的下标可以是一个JavaScript表达式,这样就可以在运行的时候动态影响form。我们将在B2.4详细讲述。
我们也可以动态的给这个对象添加一个函数:
myObject.speakYourShoeSize=function(){
alert("shoe size : "+this.shoeSize);
}
或者使用一个预定义过的函数:
function sayHello(){
alert('hello, my shoeSize is '+this.shoeSize);
}
...
myObject.sayHello=sayHello;
注意一下,我们在指定预定义的函数时,没有使用括号。如果我们写成:
myObject.sayHello=sayHello();
那么结果就是立刻执行了sayHello这个函数,并且把函数的返回值,在这里就是null返回给myObject的sayHello属性。
我们还可以通过将一个对象赋给另外一个对象来建立复杂的数据模型:
var myLibrary=new Object();
myLibrary.books=new Array();
myLibrary.books[0]=new Object();
myLibrary.books[0].title="Turnip Cultivation through the Ages";
myLibrary.books[0].authors=new Array();
var jim=new Object();
jim.name="Jim Brown";
jim.age=9;
myLibrary.books[0].authors[0]=jim;
这种方法会让人觉得有点乏味,不过JavaScript提供了一种紧凑的写法JSON,我们可以更快地组织对象图形,下面就让我们来看一下。
使用JSON
JavaScript Object Notation (JSON)是JavaScript的一个核心特征。它提供了创建数组和对象图形的简便方法,为了更好的理解JSON,我们首先要来看一下JavaScript的数组是怎样工作的,那么就先从基础看起。
JavaScript有一个内置的可以通过如下方法初始化的Array类:
myLibrary.books=new Array();
通常情况下,我们可以通过类似于普通得C语言或者Java数组的指定下标的方法来赋值,例如:
myLibrary.books[4]=somePredefinedBook;
或者通过类似于Java Map或者Python Dictionary的指定键值的方法来赋值,其实也就是JavaScript的对象方法:
myLibrary.books["BestSeller"]=somePredefinedBook;
这种写法很好调整,但是如果用来建立比较大的数组或者对象,从开始可能会比较乏味了。创建序列化的下标数组的快捷方法是用方括号,在方括号中用逗号将值隔开,就象下面这样:
myLibrary.books=[predefinedBook1,predefinedBook2,predefinedBook3];
创建一个JavaScript对象,还可以用大括号,然后再大括号中将每一个值用“键:值”对的方式记入:
myLibrary.books={
bestSeller : predefinedBook1,
cookbook : predefinedBook2,
spaceFiller : predefinedBook3
};
在这两种写法中,多余的空格都会被忽略,这样就允许我们可以自由调整格式。键也可以有空格,再JSON的写法中可以用双引号括起来,例如:
"Best Seller" : predefinedBook1,
我们可以用嵌套的方法来创建一个对复杂层级对象的的定义:
var myLibrary={
location : "my house",
keywords : [ "root vegetables", "turnip", "tedium" ],
books: [
{
title : "Turnip Cultivation through the Ages",
authors : [
{ name: "Jim Brown", age: 9 },
{ name: "Dick Turnip", age: 312 }
],
publicationDate : "long ago"
},
{
title : "Turnip Cultivation through the Ages, vol. 2",
authors : [
{ name: "Jim Brown", age: 35 }
],
publicationDate : new Date(1605,11,05)
}
]
};
在这个例子里,给myLibrary这个对象指定了三个属性,location是一个简单的字符串,keywords是一个字符串的有序列表,books则是由有序对象数组列组成的,其中每一个对象都有一个title书名(字符串),一个publicationDate出版日期(其中有一个是JavaScript的日期型,其他均为字符串型),另外还有authors作者名单(数组),每一个作者的信息都由名字和年龄组成。
JSON为我们提供了另一种简单的方法来创建这个对象,这种方法的代码行数要少于上一种方法。
眼见得读者可能已经发现,我们第二本书的出版日期使用了JavaScript的日期对象,为了指定这个值,我们可以通过JavaScript的代码,或者,用一个我们自己定义的函数:
function gunpowderPlot(){
return new Date(1605,11,05);
}
var volNum=2;
var turnipVol2={
title : "Turnip Cultivation through the Ages, vol. "
+volNum,
authors : [
{ name: "Jim Brown", age: 35 }
],
publicationDate : gunpowderPlot()
}
]
};
这样,书的名字就是通过一个内嵌的表达式自动计算出来的,而且publicationDate也背设定为通过一个预定义函数返回值取得。在前一个例子中,我们在对象创建的时候定义的一个gunpowerPlot()的函数,我们也可以为JSON调用的对象定义成员函数:
var turnipVol2={
title : "Turnip Cultivation through the Ages, vol. "+volNum,
authors : [
{ name: "Jim Brown", age: 35 }
],
publicationDate : gunpowderPlot()
}
],
summarize:function(len){
if (!len){ len=7; }
var summary=this.title+" by "
+this.authors[0].name
+" and his cronies is very boring. Z";
for (var i=0;i<len;i++){
summary+="z";
}
alert(summary);
}
};
...
turnipVol2.summarize(6);
summarize()这个函数包含了所有标准JavaScript函数应该有的特性,比方说参数,还有通过this关键字定义的对象。实际上,一旦这个对象被创建,他就是另外的一个JavaScirpt的对象,如果我们愿意的话,我们就可以把JavaScript和JSON混合起来看待。我们可以用JavaScript来调试一个再JSON中定义的对象:
var numbers={ one:1, two:2, three:3 };
numbers.five=5;
我们最初用JSON标记定一个对象,然后用普通的JavaScript来增加它的内容,同样的,我们也可以用JSON来扩展JavaScript定义的对象:
var cookbook=new Object();
cookbook.pageCount=321;
cookbook.author={
firstName: "Harry",
secondName: "Christmas",
birthdate: new Date(1900,2,29),
interests: ["cheese","whistling",
"history of lighthouse keeping"]
};
通过使用内嵌的JavaScript对象和数组类以及JSON的写法,我们可以任意的箭多层次的复杂对象,而不用担心其他的事情。JavaScript也提供了一种给面向对象的程序员轻松创建对象的方法,下面就让我们来看看它能为我们做些什么。