JavaScript中的数组类型与其他语言中的数组有着很大的区别。JavaScript中的每一项可以保存任何类型的数据。而且,JavaScript数组的大小是可以动态调整的,可以随着数据的添加自动增长以容纳新增数据。
创建数组的基本形式有两种。
1.Array构造函数
var cities = new Array();
如果预先知道要保存的项目数量,也可以给构造函数传递该数量,该数量会自动变成length属性的值。
var cities = new Array(3);
也可以向Array构造函数传递数组中应该包含的项。
var cities = new Array("shanghai", "beijing", "shenzhen");
在创建数组时可以省略new操作符:
var cities = Array(3); //创建一个包含3个元素的数组
2.数组字面量表示法
数组字面量表示法由一对包含数组项的方括号表示,多个数组项之间以逗号隔开,如下:
var cities = ["shanghai", "beijing", "shenzhen"]; var cities = []; // 创建一个空字符串
在读取和设置数组的值时,要使用方括号并提供相应值的基于0(基于0就是从0开始计数,第一项为0,第二项为1,以此类推)的数字索引,如下所示:
var cities = ["shanghai", "beijing", "shenzhen"]; alert(cities[0]); // "shanghai" cities[1] = "hongkong"; // 修改第二项"beijing"为"hongkong" cities[3] = "taiwan" // 新增一项
数组的项数保存在length属性中,它不是只读的。因此,可以通过设置length属性,可以从数组的末尾移除项或者向数组中添加新项。
var cities = ["shanghai", "beijing", "shenzhen"]; cities.length = 2; alert(cities[2]); // undefined
利用length的这一属性可以在数组末尾添加新项:
var cities = ["shanghai", "beijing", "shenzhen"]; cities[cities.length] = "hongkong";
2.1 检测数组
ECMAScript5新增了Array.isArray()方法,作用就是确定某个值到底是不是数组,而不管它是哪个全局执行环境中创建的。用法如下:
if (Array.isArray(value)) { // 对数组执行某些操作 }
2.2 转换方法
所有对象都具有toLocaleString()、toString()和valueOf()方法。其中调用数组的toString()方法会返回由数组中的每个值的字符串形式拼接而成的一个以逗号分隔的字符串。例如:
var cities = ["shanghai", "beijing", "shenzhen"]; alert(cities.toString()); // shanghai,beijing,shenzhen alert(cities.valueOf()); // shanghai,beijing,shenzhen alert(cities); // shanghai,beijing,shenzhen
说明:由于alert()需要接收字符串参数,它会在后台调用toString()方法,因此会得到直接调用toString()方法相同的结果。
另外,toLocaleString()方法经常也会返回与toString()和valueOf()相同的值,不同的是,为了取得每一项的值,调用的是每一项的toLocaleString()方法,而不是toString()方法。例如:
var p1 = { toLocaleString: function () { return "p1 toLocaleString"; }, toString: function () { return "p1 toString"; } }; var p2 = { toLocaleString: function () { return "p2 toLocaleString"; }, toString: function () { return "p2 toString"; } }; var p = [p1, p2]; alert(p); alert(p.toString()); alert(p.toLocaleString());
结果显示第一行和第二行调用的是toString方法,第三行调用的是toLocaleString方法。
数组继承的toLocaleString()、toString()和valueOf()方法,在默认情况下,都会以逗号分隔字符串的形式返回数组项。通过join()
方法,则可以使用不同的字符来分割字符串,然后返回包含所有数组项的字符串。
var cities = ["shanghai", "beijing", "shenzhen"]; alert(cities); // shanghai,beijing,shenzhen alert(cities.join(","));// shanghai,beijing,shenzhen alert(cities.join("|"));// shanghai|beijing|shenzhen
2.3 栈方法
栈是一种后进先出(LIFO)的数据结构,栈中数据项的插入和移除只能发生在栈的顶部。JavaScript数组提供了push()和pop()方法用于实现类似于栈的行为。
push()方法
可以接收任意数量的参数,把它们添加到数组的末尾,并修改数组的长度。
var params = new Array(); var count = params.push("a", "b"); alert(params); // a,b alert(count); // 2
从上面的例子可以看出,push()方法返回的插入的项数。
pop()方法
从数组的末尾移除最后一项,减少数组的长度,返回移除的项。
var params = new Array(); var count = params.push("a", "b", "c"); var item = params.pop(); alert(item); // c alert(params.length); // 2
2.4 队列方法
队列的数据结构的访问规则是先进先出(FIFO),即从队列的末端添加项,从队列的前端移除项。
shift()方法
JavaScript中提供了shift()方法,移除数组中的第一项并返回该项,同时修改数组的length属性。
var params = new Array(); var count = params.push("a", "b", "c"); var item = params.shift(); // 取得第一项 alert(item); // a alert(params.length); // 2
unshift()方法
JavaScript还提供了unshift()方法,能在数组前端添加任意个项并返回新数组的长度。
var params = new Array(); var count1 = params.unshift("a"); alert(count1); // 1 alert(params); // a var count2 = params.unshift("b"); alert(count2); // 2 alert(params); // b,a var count3 = params.unshift("c", "d"); alert(params); // c,d,b,a
观察发现,如果一次unshift()中有多项,它会将这些项按照顺序插入到数组中,即第一个参数插入最前面。像上面的例子中那样,第一次插入“a”,第二次在数组的最前面插入“b”,第三次时有多项,但是顺序是c在前,d在后。
2.5 重排序方法
数组中提供了两个直接用来重排序的方法。
reverse()方法
reverse()方法会反转数组项的顺序。
var values = [1,2,3,4,5]; values.reverse(); alert(values); // 5,4,3,2,1
sort()方法
在默认情况下,sort()方法按升序排列数组项。为了实现排序,sort()方法会调用每个数组项的toString()转型方法,然后比较得到的字符串。因此,sort()方法比较的是字符串。
var values = [3,5,53,2,34]; values.sort(); alert(values); // 2,3,34,5,53
然而,我们可以说这种排序基本是毫无意义的,我们需要的是对数值进行排序。sort()方法可以接收一个比较函数作为参数,以便指定排序规则。
比较函数接收两个参数,如果第一个参数应该位于第二个参数之前则返回一个负数,如果两个参数相等则返回0,如果第一个参数位于第二个参数之后则返回一个正数。
function compare(value1, value2) { if (value1 < value2) { return -1; } else if (value1 > value2) { return 1; } else { return 0; } } var values = [3,5,53,2,34]; values.sort(compare); alert(values); // 2,3,4,34,53
2.6 操作方法
concat()方法
可以基于当前数组中的所有项创建一个新数组。这个方法会创建一个当前数组的副本,然后将参数添加到副本的末尾,然后返回新构建的数组。如果传递给concat()方法的是一个或多个数组,则会将该数组中的每一项添加到数组中。
var arrays = ["a", "b", "c"]; var arrays2 = arrays.concat("d", ["e", "fe"]); alert(arrays); // a,b,c alert(arrays2); // a,b,c,d,e,f
slice()方法
基于当前数组中的一或多个项创建一个新数组。slice()方法可以接收一个或两个参数,即要返回项的起始和结束位置。当只要一个参数,返回从起始项到数组末尾的所有项,当有两个参数时,返回起始位置和结束位置之间的项(不包括结束项)。slice()方法不会影响原数组。
var cities = ["beijing", "shanghai", "shenzhen", "guangzhou"]; var cities2 = cities.slice(1); var cities3 = cities.slice(1,3); alert(cities2); // shanghai,shenzhen,guangzhou alert(cities3); // shanghai,shenzhen
splice()方法
splice()方法主要用于向数组的中部插入项,使用方式有3种:
- 删除 可以删除任意数量的项,指定2个参数:要删除的第一项和删除的项数,如:splice(1,3)会删除数组中的第2、3、4项
var cities = ["beijing", "shanghai", "shenzhen", "guangzhou"]; cities.splice(1,3); alert(cities); // beijing
- 插入 可以向指定位置插入任意数量的项。指定3个参数:起始位置、0(要删除的项数)、要插入的项
var cities = ["beijing", "shanghai", "shenzhen", "guangzhou"]; cities.splice(1,0,"hongkong"); alert(cities); // beijing,hongkong,shanghai,shenzhen,guangzhou
- 替换 可以替换指定位置的项。指定3个参数:起始位置、要删除的项、要插入的任意项。
var cities = ["beijing", "shanghai", "shenzhen", "guangzhou"]; cities.splice(1,2,"hongkong"); alert(cities); // beijing,hongkong,guangzhou
2.7 位置方法
JavaScript中有两个位置方法:indexOf()方法和lastIndexOf()方法。这两个方法都接收两个参数:要查找的项和(可选)表示查找起点位置的索引。
indexOf()方法表示从数组的开头向后查找,lastIndexOf()则从数组的末尾开始向前查找。它们都返回查找的项在数组中的位置,如果没有找到则返回-1。在第一个参数与数组中的每一项比较时使用的是全等。
var nums = [1,2,3,4,5,6]; alert(nums.indexOf(3)); // 2 alert(nums.lastIndexOf(5)); // 4 alert(nums.indexOf(3,1)); // 2 alert(nums.lastIndexOf(4,4)); // 3
2.8 迭代方法
JavaScript为数组提供了5个迭代方法。每个方法接收两个参数:要在每一项上运行的函数和(可选)运行该函数的作用域对象——影响this的值。需要传入的参数:数组项的值、该项在数组中的位置和数组对象本身。
- every():对数组中的每一项运行给定函数,如果该行数对每一项都返回true,则返回true
- filter():对数组中的每一项运行给定函数,返回会返回true的项组成的数组
- foreEach():对数组中的每一项运行给定函数,没有返回值
- map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的函数。
- some():对数组中的每一项运行给定函数,如果任一项返回true,则函数返回true
以上方法都不会修改数组中包含的值。
2.9 归并方法
JavaScript中有两个归并数组的方法:reduce()和reduceRight()。这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。其中,reduce()方法从数组第一项开始,而reduceRight()则从数组的最后一项开始。
它们都可以接收两个参数:一个在每一项上调用的函数和(可选)作为归并基础的初始值。传递给reduce()和reduceRight()的函数接收4个参数:前一个值、当前值、项的索引和数组对象。这个函数返回的任何值都会作为第一个参数自动传给下一项。第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二个参数就是数组的第二项。
var values = [1,2,3,4,5]; var sum = values.reduce(function(prev, cur, index, array){ return prev+cur; }); alert(sum); // 15
第一次执行回调函数,prev是1,cur是2。第二次,prev是3(1+2),cur是3(数组第三项的值),知道每一项都访问到。
reduceRight()的作用类似,只不过方向相反而已。