3.1 数组
数组用于保存一组相关的数据。数组中的数据项称为数组元素。数组元素在数组中的位置称为下标。JavaScript数组下标最小值为0。数组元素用数组名和下标来表示。例如,假设a数组中有3个数组元素,这3个元素可表示为a[0]、a[1]和a[2]。
数组
JavaScript是弱类型的,所以数组中的各个数组元素可存放各种不同类型的数据,甚至可以是对象或数组。JavaScript不支持多维数组,但可通过在数组元素中保存数组来模拟多维数组。
JavaScript的数组本质上也是一种对象。用typeof函数测试数组,其返回值为object。
3.1.1 创建数组
JavaScript提供了两种创建数组的方法。
1. 使用直接量创建数组
可将“[”和“]”括起来的一组数据(用逗号分隔)赋值给变量来创建数组。例如:
var a=[] //创建一个空数组 var b=[1,2,3] //b[0]=1、b[1]=2、b[2]=3 var c=["abc",true,100] //c[0]="abc"、c[1]=true、c[2]=100
数组元素也可以是一个数组。例如:
var a=[1,2],[3,4,5] //a[0][0]=1、a[0][1]=2、a[1][0]=3、a[1][1]=4、a[1][2]=5
2. 使用Array构造函数创建数组
数组对象的构造函数为Array(),可用它来创建数组。例如:
var a=new Aray() //创建一个空数组 var b=new Array(1,true,"abc") //b[0]=1、b[1]=true、b[2]= "abc"
关键字new用于调用构造函数,创建新对象。
一种特殊情况是,在用一个整数作为Array构造函数参数时,该整数作为数组的大小。例如:
var a=new Aray(3) //创建一个包含3个元素的数组
3.1.2 使用数组
1. 使用数组元素
数组元素通过数组名和下标进行引用。一个数组元素等同一个变量。可以为数组元素赋值,或将其用于各种运算。
【例3-1】 使用数组元素。源文件:03\test3-1.html。
… <body> <script> var a = new Array(3) //创建数组 a[0] = 1 //为数组元素赋值 a[1] = 2 a[2] = a[1] + a[0] //将数组元素用于计算 document.write('a[0]=') document.write(a[0]) //直接输出数组元素 document.write('<br>a[1]=' + a[1]) //数组元素用于字符串连接 document.write('<br>a[2]=' + a[2]) document.write('<br>a=' + a) //数组用于字符串连接 </script> </body> </html>
在浏览器中的运行结果如图3-1所示。
图3-1 使用数组元素
在将数组用于字符串操作时,JavaScript会调用数组对象的toString()方法将其转为字符串。JavaScript的大多数内置对象均有toString()方法,用于将对象转换为字符串。
2. 关于多维数组
JavaScript没有多维数组的概念,但可在数组元素中保存一个数组。
【例3-2】 在数组元素中存放数组。源文件:03\test3-2.html。
… <body> <script> var a = new Array(3) a[0] = 1 a[1] = new Array(1,2) //将数组存入数组元素 a[2] = new Array('ab', 'cd', 'ef') document.write('a[0]=' + a[0] + " 其数据类型为:" + typeof a[0]) document.write('<br>a[1]=' + a[1] + " 其数据类型为:" + typeof a[1]) document.write('<br>a[2]=' + a[2] + " 其数据类型为:" + typeof a[2]) </script> </body> </html>
在浏览器中的运行结果如图3-2所示。
图3-2 在数组元素中存放数组
3. 关于数组下标范围
在JavaScript中,数组下标最小值为0,最大值为数组长度减1。JavaScript没有数组下标超出范围的概念。当使用了超出范围的下标时,JavaScript不会报错,引用的数组元素相当于未声明的变量,其值为undefined。对超出范围的下标引用的数组元素赋值时,会为数组添加数组元素。
【例3-3】 使用下标超出范围的数组元素。源文件:03\test3-3.html。
… <body> <script> var a = new Array(1,2,3) document.write('数组a=' + a + '<br>') document.write('a[4]=' + a[4]+'<br>') //a[4]不存在,下标超出了范围 x = a[4] + 100 //计算undefinded + 100 document.write('a[4] + 100=' + x) a[4] = "abcd" // a[4]不存在,为数组添加该元素 document.write('<br>赋值后,a[4]=' + a[4]) document.write('<br>数组a=' + a + '<br>') </script> </body> </html>
在浏览器中的运行结果如图3-3所示。
图3-3 使用下标超出范围的数组元素
4. 数组赋值
JavaScript允许将数组赋值给另一个变量。如果将一个存放了数组的变量赋值给另一个变量,则这两个变量引用的是同一个数组。通过其中任意一个变量对数组进行操作,另一个变量立即反映其变化(因为引用的是同一个数组)。
将一个数组直接赋值给变量时,会覆盖其以前存放的数组。
【例3-4】 使用数组赋值。源文件:03\test3-4.html。
… <body> <script> var a = new Array(1, 2, 3) var b=a document.write('数组a=' + a + '<br>') document.write('数组b=' + b + '<br>') b[0] = 100 document.write('数组a=' + a + '<br>') document.write('数组b=' + b + '<br>') a = ['ab', 'cd'] document.write('数组a=' + a + '<br>') document.write('数组b=' + b + '<br>') document.write('a[2]=' + a[2]) //a[2]的值为undefined,说明原来的数组已被覆盖 </script> </body> </html>
在浏览器中的运行结果如图3-4所示。
图3-4 使用数组赋值
5. 添加、删除数组元素
JavaScript中的数组长度是不固定的,对不存在的数组元素赋值时,会将其添加到数组中。例如:
var a = new Array() //创建一个空数组 a[0] = 1 //添加数组元素 a[1] = 2
delete关键字可用于删除数组元素。例如:
delete a[1] //删除a[1]
需注意的是,delete的实质是删除变量所引用的内存单元。使用delete删除一个数组元素后,数组的大小不会改变。引用一个被删除的数组元素,得到的值为undefined。
【例3-5】 添加、删除数组元素。源文件:03\test3-5.html。
… <body> <script> var a = new Array() //创建一个空数组 a[0] = 1 //添加数组元素 a[1] = 2 a[2] = 3 document.write('数组长度为:' + a.length) for (i = 0; i < 3; i++) document.write("<br>a[" + i + "]=" + a[i]) //输出数组元素 delete a[1] //删除a[1] document.write('<br>delete a[1]后,数组长度为:' + a.length) for (i = 0; i < 3; i++) document.write("<br>a[" + i + "]=" + a[i]) //输出数组元素 </script> </body> </html>
在浏览器中的运行结果如图3-5所示。
图3-5 添加、删除数组元素
6. 数组迭代
数组通常结合循环实现数组迭代(或者叫数组元素遍历)。因为数组下标最小值为0,最大值为数组长度减1。一般情况下,对数组a用for循环“for (var i = 0; i < a.length; i++)”即可实现数组迭代。如果数组元素已经使用delete被删除,或者通过赋值语句给一个下标较大的不存在的数组元素赋值,就会导致数组包含一些不存在的元素。使用for/in循环可忽略不存在的元素。
【例3-6】 数组迭代操作。源文件:03\test3-6.html。
… <body> <script> var a = new Array(100, 200, 300, 400, 500) for (i = 0, len = a.length; i < len; i++) a[i] += 10 //每个数组元素加上10 document.write('<br>标准for循环遍历数组元素:') for (i = 0, len = a.length; i < len; i++) document.write(a[i] + " ") //输出数组元素 for (x in a) a[x] += 20 //每个数组元素加上20 document.write('<br>for/in循环遍历数组元素:') for (x in a) document.write(a[x] + " ") //输出数组元素下标 delete a[1] //a[1]被删除,不存在了 a[7] = 700 //a[5]、a[6]不存在 document.write('<br>标准for循环遍历数组元素:') for (i = 0, len = a.length; i < len; i++) document.write(a[i] + " ") //输出数组元素 document.write('<br>for/in循环遍历数组元素:') for (x in a) document.write(a[x] + " ") //输出数组元素下标 </script> </body> </html>
在浏览器中的运行结果如图3-6所示。
图3-6 数组迭代操作
脚本中使用了两种for循环。标准的for循环“for (i = 0, len = a.length; i < len; i++)”中,循环变量i用来迭代数组下标。注意,这里的“len = a.length”只执行一次。如果将for循环改为“for (i = 0; i < a.length; i++)”,则每次循环都会查询数组的长度,效率降低了。
for/in循环通常用于迭代对象的属性,在本例的“for (x in a)”中,x用于迭代数组a的有效下标。
3.1.3 数组的属性
1. length
数组的length属性用于获得数组长度。例如,a.length获得数组a的长度。JavaScript数组的长度是可变的,通过为不存在的数组元素赋值的方式添加数组元素时,数组的长度也随之变化。例如:
var a = new Aray(1, 2, 3) //创建数组,数组长度为3 a[5] = 10 //添加一个数组元素,数组长度变为6
数组a的原长度为3,执行“a[5] = 10”后,其长度变为6。因为数组的长度始终为最后一个元素的下标加1。数组中没有赋值的元素的值为undefined。
数组长度为数组中元素的个数。因为数组元素下标从0开始,所以数组下标范围为0到长度-1。
JavaScript允许修改length属性。例如:
a.length=5
上面的语句将数组a的长度修改为5。如果修改后的长度小于原来长度,超出新长度的数组元素丢失。如果新长度超出原长度,增加的数组元素初始值为undefined。
【例3-7】 使用数组的length属性。源文件:03\test3-7.html。
… <body> <script> var a = new Array(1,2) document.write('数组长度为:' + a.length) a.length = 3 document.write('<br>修改后,数组长度为:' + a.length) for (var i = 0; i < a.length;i++) document.write(" a[" + i + "]=" + a[i] + ' ') a[2] = 3 a[3] = 4 //添加数组元素 document.write('<br>数组长度为:' + a.length) for (var i = 0; i < a.length; i++) document.write(" a[" + i + "]=" + a[i] + ' ') a.length = 2 //减小数组长度,超出范围的数组元素被删除 document.write('<br>数组长度为:' + a.length) for (var i = 0; i < a.length; i++) document.write(" a[" + i + "]=" + a[i] + ' ') a.length = 5 //减小数组长度,超出范围的数组元素被删除 document.write('<br>数组长度为:' + a.length) for (var i = 0; i < a.length; i++) document.write(" a[" + i + "]=" + a[i] + ' ') </script> </body> </html>
在浏览器中的运行结果如图3-7所示。
图3-7 使用数组的length属性
2. prototype属性
对象的prototype属性用于为对象添加自定义的属性或方法。为数组添加自定义属性或方法的基本语法格式如下。
Array.prototype.name = value
其中,name为自定义的属性或方法名称,value为表达式或者函数。自定义属性和方法对当前页面中的所有数组有效。
【例3-8】 为数组添加自定义属性和方法。源文件:03\test3-8.html。
… <body> <script> Array.prototype.tag="test3-8.html" //添加自定义属性 Array.prototype.sum = function () { //添加自定义方法,对数组中的所有元素求和 var s = 0 for (var i = 0; i < this.length;i++) s += this[i] return s } Array.prototype.print = function () { //添加自定义方法,将数组中的所有元素输出到浏览器 for (var i = 0; i < this.length; i++) document.write(this[i] +" ") } var a = new Array(1, 2, 3, 4, 5) document.write('当前环境:' + a.tag) document.write('<br>数组a中的数据为:') a.print() document.write('<br>数组a中的数据的和为:' + a.sum()) var b = new Array(2,4,6) document.write('<br><br>当前环境:' + b.tag) document.write('<br>数组b中的数据为:') b.print() document.write('<br>数组b中的数据的和为:' + b.sum()) </script> </body> </html>
在浏览器中的运行结果如图3-8所示。
图3-8 为数组添加自定义属性和方法
3.1.4 数组的方法
JavaScript内置的Array类提供了一系列方法用于操作数组。
1. 连接数组
join方法用于将数组中的所有元素连接成一个字符串,字符串中的各个数据默认用逗号分隔。也可为join方法指定一个字符串作为分隔符。
基本语法格式为:
a.join() //将数组a中的数据连接成逗号分隔的字符串 a.join(x) //将数组a中的数据连接成变量x中的字符串分隔的字符串
【例3-9】 使用join方法。源文件:03\test3-9.html。
… <body> <script> var a = new Array(1, 2, 3) document.write(a.join()) //输出1,2,3 document.write('<br>') document.write(a.join('@#')) //输出1@#2@#3 </script> </body> </html>
在浏览器中的运行结果如图3-9所示。
图3-9 使用join方法
2. 逆转元素顺序
reverse方法将数组元素以相反的顺序存放。基本语法格式如下。
a.reverse()
【例3-10】 逆转元素顺序。源文件:03\test3-10.html。
… <body> <script> var a = new Array(1, 2, 3) document.write('逆转前:' + a) a.reverse() document.write('<br>逆转后:' + a) </script> </body> </html>
在浏览器中的运行结果如图3-10所示。
图3-10 使用reverse方法
3. 数组排序
sort方法用于对数组排序。默认情况下,数组元素按字母顺序排序,数值会转换为字符串进行排序。
可以为sort方法提供一个排序函数作为参数,排序函数定义排序规则。排序函数有两个参数,设为x和y。若需x排在y之前,则排序函数应返回一个小于0的值。若需x排在y之后,则排序函数应返回一个大于0的值。若两个参数的位置无关紧要,比较函数返回0。
【例3-11】 数组排序。源文件:03\test3-11.html。
… <body> <script> var b = ["One", "Two", "Three", "Four"] document.write('<br>排序前:' + b) b.sort() document.write('<br>排序后:' + b) var c = [2, 12, 3, 23] document.write('<br>排序前:' + c) c.sort() document.write('<br>排序后:' + c) var b = [2, 12, 3, 23] document.write('<br>排序前:' + b) b.sort(function (x, y) { return x - y }) document.write('<br>排序后:' + b) b.sort(function (x, y) { return y - x }) document.write('<br>排序后:' + b) </script> </body> </html>
在浏览器中的运行结果如图3-11所示。
图3-11 数组排序
4. 子数组
slice方法用于从数组中取子数组,其基本语法格式如下。
数组名.slice(x,y)
从数组中返回下标范围为x~y-1的子数组。如果省略y,则返回从x开始到最后的全部数组元素。如果x或y为负数,则作为和最后一个元素的相对位置。
【例3-12】 使用slice方法。源文件:03\test3-12.html。
… <body> <script> var a = [1, 2, 3, 4, 5, 6, 7] document.write('<br>原数组:' + a) b = a.slice(1, 4) document.write('<br>a.slice(1, 4)= '+ b) b = a.slice(4) document.write('<br>a.slice(4)= '+ b) b = a.slice(1, -1) document.write('<br>a.slice(1, -1)= '+ b) b = a.slice(-3, -1) document.write('<br>a.slice(-3, -1)= '+ b) </script> </body> </html>
在浏览器中的运行结果如图3-12所示。
图3-12 使用slice方法
5. 添加、删除数组元素
splice方法用于添加或删除数组元素,其基本语法格式如下。
数组名.splice(m,n,x1,x2,…)
其中,m为开始元素下标,n为从数组中删除的元素个数。x1、x2等是要添加到数组中的数据,可以省略。splice方法同时会返回删除的数组元素。
【例3-13】 添加、删除数组元素。源文件:03\test3-13.html。
… <body> <script> var b = [1, 2, 3, 4, 5, 6, 7] document.write('<br>原数组:' + b) a = b.splice(3, 2) document.write('<br>a=' + a + " b=" + b) a = b.splice(2, 2, "a", "b", "c") document.write('<br>a=' + a + " b=" + b) </script> </body> </html>
在浏览器中的运行结果如图3-13所示。
图3-13 添加、删除数组元素
6. push和pop方法
push和pop方法用于实现数组的堆栈操作(先进后出)。push方法将数据添加到数组末尾,返回数组长度。pop方法返回数组中的最后一个元素,数组长度减1。
【例3-14】 数组的堆栈操作。源文件:03\test3-14.html。
… <body> <script> var a = [] n = a.push(1, 3, 5) document.write('n=' + n + " a=" + a) n = a.pop() document.write('<br>n=' + n + " a=" + a) n = a.push("abc") document.write('<br>n=' + n + " a=" + a) </script> </body> </html>
在浏览器中的运行结果如图3-14所示。
图3-14 数组的堆栈操作
7. unshift和shift方法
unshift和shift方法用于实现数组的队列操作(先进先出)。unshift方法将数据添加到数组开头,并返回新的数组长度。shift方法返回数组中的第一个元素,所有数组元素依次前移一位,数组长度减1。
【例3-15】 数组的队列操作。源文件:03\test3-15.html。
… <body> <script> var a = [] n = a.unshift(1, 3, 5) document.write('n=' + n + " a=" + a) n = a.shift() document.write('<br>n=' + n + " a=" + a) n = a.unshift("abc") document.write('<br>n=' + n + " a=" + a) </script> </body> </html>
在浏览器中的运行结果如图3-15所示。
图3-15 数组的队列操作
8. 合并数组
concat方法用于将提供的数据合并成一个新的数组,其基本语法格式如下。
b = a.concat(x1,x2,x3,…)
其中,x1、x2、x3等是单个的数据或者数组变量。如果是数组变量,则将其中的数据合并到新数组中。变量b保存合并后的新数组。
【例3-16】 合并数组。源文件:03\test3-16.html。
… <body> <script> var a = [10, 20], b = ['a', 'b'] c = a.concat(1, 3, 5) document.write('<br>a=' + a + 'c=' + c) c = a.concat(2, 4, b) document.write('<br>a=' + a + 'c=' + c) </script> </body> </html>
在浏览器中的运行结果如图3-16所示。
图3-16 数组合并