且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《JavaScript和jQuery实战手册(原书第2版)》——2.8节数组

更新时间:2022-09-28 09:57:37

2.8 数组
上一小节中使用的简单变量只是保存了一段信息,例如一个数字或一个字符串值。当你只需要记录分数、年龄或总价这样的单个内容的时候,它们做得很好。然而,如果需要存储一组相关的项目,例如,一个星期中的所有的星期几名称,或者Web页面上所有图像的一个列表,此时简单的变量并不是很方便使用。
例如,假设已经创建了一个JavaScript购物车系统,它记录了访问者想要购买的商品,如果想要使用简单的变量来记录访问者添加到购物车中的所有商品,必须像下面这样编写代码:

var item1 = 'Xbox 360';
var item2 = 'Tennis shoes';
var item3 = 'Gift certificate';

但是,如果想要添加更多的商品,该怎么办呢?必须创建更多的变量,item4、item5等。并且,由于不知道访问者想要购买多少商品,我们确实不知道应该创建多少变量。
好在JavaScript为记录项目列表提供了一种更好的方法——数组。数组是在单个地方存储多个值的一种方式。把数组当成是一个购物列表。当需要去杂货店的时候,我们坐下来并写下要购买的商品的列表。如果此前几天刚刚去过杂货店购物,这个列表可能只包含一些商品,但是,如果储存的食品已经很少了,这个购物列表可能相当长。不管列表中有多少商品,它还都只是一个列表。
不使用数组的话,我们必须为列表中的每个商品创建一个变量。例如,想象一下,我们无法在单独的一张纸上记录下商品列表,而是必须使用一叠纸片,每张纸片用于记录要购买的一项商品。如果想要添加其他需要购买的商品,就需要一张新的纸片,然后,在购物的时候按照每个纸片去进行(如图2-5所示)。这就是简单变量的工作方式。但是,通过使用数组,我们可以创建商品的一个单独的列表,并且甚至可以随时添加、删除或修改商品。


《JavaScript和jQuery实战手册(原书第2版)》——2.8节数组

2.8.1 创建数组
要创建数组并在数组中存储项目,首先声明数组的名称(就像我们对一个变量所做的一样),然后提供逗号分隔的值的一个列表:每个值表示列表中的一个项目。和变量一样,数组的名称也取决于我们自己,但是需要遵守2.4.1节列出的命名规则。要表示一个数组,可以把项目列表放在开始方括号和结束方括号之间:

var days = ['Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun'];

方括号[ ]非常重要,它们告诉JavaScript解释器将要处理一个数组。我们可以创建一个空的没有任何元素的数组:

var playList = [];

创建一个空的数组,等同于2.4.1小节所介绍的声明一个变量。当在程序运行时才向数组添加项目的情况下,我们将创建一个空的数组。例如,上面的数组可能用来记录某人从Web页面上的一个列表中选择的歌曲,此前我们不知道他将要选择哪些歌曲,因此声明了一个空的数组并且随后用他选择的歌曲来填充项目(向数组添加项目将在2.8.3节介绍)。
注意: 在浏览其他人的JavaScript程序(或其他的JavaScript图书)的时候,我们可能会遇到另一种创建数组的方式,即使用Array关键字,如下所示:

    var days = new Array('Mon', 'Tues', 'Wed');

这种方法也是有效的,但是,本书中使用的方法(叫做数组直接量)需要更少的录入和更短的代码。
可以把值的任何混合形式存储到一个数组中。换句话说,数值、字符串和Boolean值都可以出现在同一个数组中:

var prefs = [1, 223, 'www.oreilly.com', false];

注意: 我们甚至可以把数组和其他对象作为元素存储到数组中。这有助于存储复杂的数据。
上面这个数组的例子展示了在单独一行代码内创建数组。然而,如果我们已经有了很多要添加的项目,或者项目是较长的字符串,那么,试图在一行代码中输入所有内容会使得程序难以阅读。在这种情况下,很多程序员选择另一种方法,即通过数行代码创建一个数组,如下所示:

var authors = [ 'Ernest Hemingway',
               'Charlotte Bronte',
                'Dante Alighieri',
                'Emily Dickinson'
                ];

正如2.4.2节中的“常见问题:JavaScript中的空格、制表符和回车”部分所介绍的,JavaScript解释器会忽略额外的空格和分行符号,因此,即便这段代码分5行显示,它仍然是一条语句,最后一行的分号表明了这一点。
提示: 要让名字像上面那样排列,可以输入第一行var authors = ['Ernest Hemingway',按下回车键,然后多次按下空格键直到换到新行,输入下一个值'Charlotte Bronte',。
2.8.2 访问数组中的项目
我们可以使用变量名来访问一个简单变量的内容。例如,alert(lastName)打开一个警告框,该警告框带有变量lastName中存储的值。然而,因为数组可以存储多个值,我们不能只使用其名字来访问其中包含的项目。一个叫做索引的唯一编号表示了数组中每个项目的位置。要访问数组中的一个特定项目,我们使用项目的索引编号。例如,假设已经创建了一个数组,其中包含了星期几的缩写,并且我们想要打开一个警告框来显示第一个项目。可以这样编写代码:

var days = ['Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun'];
alert(days[0]);

这段代码打开一个其中显示‘Mon’的警告框。数组是从0开始索引的,意味着数组中的第一项的索引值为0,第二项的索引值为1,换句话说,从项目在列表中的位置减去1就得到了其索引值,第5项的索引值是5—1,即4。当你刚开始编程时,从0开始索引确实容易令人混淆,因此,表2-4展示了(上面的例子中的)数组days是如何索引的、它包含的值以及如何访问每个值。
表2-4:数组中的项目必须使用一个索引编号来访问,这个索引编号等于它在列表中的位置减去1


《JavaScript和jQuery实战手册(原书第2版)》——2.8节数组

可以通过给索引位置赋一个新值来改变数组中一个项目的值。例如,要把一个新值放入数组days的第一个项目中,可以这样编写:

days[0] = 'Monday';

由于数组中的最后一项的索引编号总是比数组中的项目的总数小1,因此,要访问最后一项,只需要知道数组中有多少项目就可以了。这是一项容易的任务,因为每个数组都有一个length属性,它包含了数组中项目的总数。要访问length属性,可以在数组名称的后面添加一个点号,然后跟着length。例如,days.length返回数组days中包含的项目数(如果创建了一个不同的数组,例如playList,获得其长度的方法是:playList.length)。因此,可以使用简短的JavaScript代码来访问数组的最后一项所存储的值:

days[days.length-1]

上面的代码段说明了我们不一定必须为索引提供一个直接量数值(例如,days[0]中的0)。我们也可以提供一个返回有效数值的表达式:在这个例子中,days.length-1是一个简短的表达式,它首先获取days数组中项目的数目(在这个例子中是7),并且用它减去1。因此,在这个例子中,days[days.length-1]变成了days[6]。
还可以使用包含数值的一个变量来作为索引:

var i = 0;
alert(days[i]);

上面代码的最后一行等价于alert(days[0]);。当在3.3节用到循环的时候,会发现这一技术特别有用。
2.8.3 向数组添加项目
假设我们创建了一个数组来记录用户在Web页面上单击的项目。每次用户单击页面,就向数组添加一个项目。JavaScript提供了向数组添加内容的几种方式。
在数组的末尾添加一个项目
要在数组的末尾添加一个项目,可以使用2.8.2节介绍的索引表示法,使用比列表中的最后一项大1的一个索引值。例如,假设已经创建了一个名为properties的数组:

var properties = ['red', '14px', 'Arial'];
此时,数组有3个项目。别忘了,可以使用比项目总数小1的一个索引来访问数组最后一项,因此,在这个例子中,数组中的最后一项是properties[2]。要添加另外一项,可以这么做:
properties[3] = 'bold';
这行代码在数组的第4个位置插入了'bold',这就创建了拥有4个元素的一个数组,即['red', '14px', 'Arial', 'bold']。注意,当添加一个新项目的时候,我们使用了等于数组中当前元素的总数的一个索引值,因此,可以通过使用数组的length属性作为索引从而确保总是在数组的末尾添加一项。例如,可以把上面的这行代码重写成如下:
properties[properties.length] = 'bold';
也可以使用数组的push()命令,它将我们所提供的圆括号之间的内容添加到数组的末尾。和使用length属性一样,通过在数组名的后面添加一个点号再跟着push()来使用该命令。例如,下面是在properties数组末尾添加一项的另一种方法:
properties.push('bold');
在圆括号中提供的任何内容(在这个例子中是字符串'bold'),都将作为一个新项目添加到数组的末尾。我们可以使用任何一种类型的值,如字符串、数值、Boolean或者甚至一个变量。
push()命令的一个优点是:允许向数组中添加多个项目。例如,假设想要在名为properties的数组末尾添加3个值,可以像下面这样做:
properties.push('bold', 'italic', 'underlined');
在数组的开头添加一项
如果想要在数组的开头添加一项,可以使用unshift()命令。下面是在properties数组的开头添加'bold'值的一个例子:
var properties = ['red', '14px', 'Arial'];
properties.unshift('bold');

这段代码运行之后,数组properties包含4个元素:['bold', 'red', '14px', 'Arial']。和push()一样,我们可以使用unshift()在数组的开始处插入多个项目:

properties.unshift('bold', 'italic', 'underlined');

注意: 确保使用的时候,在数组名的后面跟着一个点号和想要使用的方法。换句话说,push('new item')是无效的。必须先使用数组名(就是在创建数组时给数组的名字),然后跟着一个点号,然后是方法,例如: authors.push('Stephen King');。
选择如何向数组添加项目
到目前为止,本章介绍了向数组添加项目的3种方法。表2-5比较了这些技术。这些命令中的每一个都完成相似的任务,因此可以根据程序的情况来选择其中一种。如果存储在数组中的项目的顺序无关紧要,那么,这些方法中的任何一种都可以使用。例如,假设有一个产品图片的页面,并且单击一个图片就会把产品添加到购物车中。可以使用一个数组存储购物车商品。商品出现在购物车(或数组)中的顺序无关紧要,因此可以使用上述技术中的任何一种。
然而,如果创建一个数组来记录某些事情发生的顺序,那么就与选择的方法有关系了。例如,假设要创建一个页面,它允许访问者通过单击页面上的歌名来创建一个歌曲播放列表。既然播放列表中的歌曲按照它们应该播放的顺序来排列,那么,顺序是很重要的。因此,访问者每次单击一首歌,这首歌曲的名字都应该出现在播放列表的末尾(因此,它将会是最后一首要播放的歌曲),那么可以使用push()方法。


《JavaScript和jQuery实战手册(原书第2版)》——2.8节数组

push()和unshift()命令返回一个值。具体来说,一旦push()和unshift()完成了任务,它们就可以提供数组中项目的数目。例如:

var p = [0,1,2,3];
var totalItems = p.push(4,5);

这段代码运行之后,totalItems中存储的值是6,因为现在p数组中有6个项目。
高级用户提示
创建队列
向数组添加项目的方法(push()和unshift())以及从数组删除项目的方法(pop() 和shift())通常一起使用,以提供按照项目创建的顺序来访问它们的方法。典型的例子就是音乐播放列表。歌曲按照它们在列表中出现的顺序播放,因此,先播放第一首歌并且随后从队列中删除它。这一安排类似于排队等候看电影。当你到达电影院,就在队列的末尾排队,当电影快要开始的时候,大门打开,队列中的第一个人首先进去。在编程领域,这一概念叫做FIFO(First In, First Out,先进先出)。可以使用数组以及push()和shift()方法来模拟这种安排。例如,假设有一个名为playlist的数组。要在队列的末尾添加一首新的歌曲,使用push()的方法如下:

playlist.push('Yellow Submarine');
要获取下一首将要播放的歌曲,可以获取列表中的第一项,如下所示:
nowPlaying = playlist.shift();

这段代码从数组中删除了第一个项目,并且将它存储在名为nowPlaying的变量中。FIFO概念对于创建和管理诸如播放列表、任务列表或者图像幻灯片这样的队列很有用。
2.8.4 从数组删除项目
如果想要从数组的末尾或开头删除一个项目,可以使用pop()或shift()命令。这两条命令都会从数组删除一个项目,pop()命令从数组末尾删除项目,而shift()从数组开始删除一个项目。表2-6比较了这两种方法。
表2-6:从数组中删除项目的两种方法


《JavaScript和jQuery实战手册(原书第2版)》——2.8节数组

与push()和unshift()一样,一旦pop()和shift()完成了从数组删除项目的任务,会返回一个值。实际上,它们返回了刚刚删除的值。例如,下面的代码删除一个值并将其存储到removedItem变量中:

var p = [0,1,2,3];
var removedItem = p.pop();

代码运行后,removedItem的值是3并且数组p现在包含[0,1,2]。
注意: 本章的文件包含了一个Web页面,可以用来交互地测试不同的数组命令。该文件的名字是array_methods.html,位于教程的testbed目录下。在Web浏览器中打开这个文件,并且单击Web页面上的各种按钮,看看数组方法是如何工作的(另外,页面的所有漂亮的交互功能都得益于JavaScript)。