与其它语言不同,ECMAScript数组的每一项可以保存任何类型的数据。
而且,ECMAScript数组的大小是动态调整的。
创建数组有两种方式:
var colors = new Array();
如果预先知道要保存的数据的数量,也可以给构造函数传递该数量,该数量也会变成length属性的值。
var colors = new Array(20);
也可以向Array构造函数传递数组项:
var colors = new Array("red","blue");
给构造函数传一个值也可以创建数组: 传递的值为数值则创建该长度的数组,传递的值为其他类型则创建只包含该值一项的数组。
在使用Array构造函数创建数组时也可以省略new操作符。
var colors = ["red","blue"];
var names = [];
var names = [1,2,]; //这样会创建包含2或3项的数组
var options = [,,,,,]; //这样会创建包含5或6项的数组
和object一样,在使用数组字面量表示法时也不会调用Array构造函数。
通过方括号和下标访问数组项,如果索引超过了数组现有项数,数组就会自动增加到该索引值加1的长度。
数组的length属性不只是只读的。通过设置length可以从数组的末尾移除项或者向数组中添加新项。(新增的项都是undefined)。
利用length属性可以方便地在数组末尾添加新项:
colors[colors.length] = "black";
是因为数组最后一项的索引是length-1,下一个新项的位置就是length。
var colors = ["red","blue"];
colors[99] = "black";
colors.length;//100,位置2到位置98都是undefined
上述的三种方法都会返回以逗号分隔的字符串形式,而join方法可以指定分隔符。如果不传参或传undefined的话默认以逗号作为分隔符。
如果数组中某一项是null或undefined,那么该值在上述四种方法的返回中以空字符串表示。
利用Array.isArray( )方法来检测某个值是否是数组。
Array.from() 方法可以将一个类数组或可迭代对象转换成数组。
//Array from a String
Array.from('foo');
// ["f", "o", "o"]
//Array from a Set
let s = new Set(['foo', window]);
Array.from(s);
// ["foo", window]
//Array from a Map
let m = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(m);
// [[1, 2], [2, 4], [4, 8]]
//Array from an Array-like object (arguments)
function f() {
return Array.from(arguments);
}
f(1, 2, 3);
// [1, 2, 3]
Array.of() 方法用于创建数组。
由于Array构造函数在只传入一个参数时有不同的意义:若为数字的话则创建相应大小的数组:
var arr = new Array(7);
//[ undefined,undefined ,undefined ,undefined ,undefined , undefined,undefined ]
但是Array.of() 方法只会将传入的参数作为数组项创建数组:
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
因此Array.of()是一个不用考虑参数类型的创建数组的好实践。
ECMAScript提供了可以让数组的行为类似于其他数据结构的方法。
结合使用push()和shift(),可以模拟队列来使用数组。
同时使用unshift()和pop(),可以反向模拟一个队列。
返回排序后的数组
sort会调用每一项的toString方法,然后比较得到的字符串。即使数组相中每一项是数值,sort比较的也是字符串。
//一个简单的比较函数
function compare(value1,value2){
if(value1return -1;
}else if(value1>value2){
return 1;
}else{
return 0;
}
}
var values = [15,10,5,1,0];
values.sort(compare);
alert(values);//0,1,5,10,15
对于数值类型或者其valueOf方法会返回数值类型的对象类型,可以使用一个更简单的比较函数来实现按数值由小到大排列:
function compare(value1,value2){
return value1-value2;
}
基于当前数组中的所有项创建一个新数组
有关参数:
var colors=["red","blue"];
var colors2 = colors.concat("yellow",["black","white"]); //"red","blue","yellow","black","white"
基于当前数组中的一或多个项创建一个新数组。不会影响原始数组。
var colors = ["red","blue","yellow","black","white"];
var colors1 = colors.slice(1); //"blue","yellow","black","white"
var colors2 = colors.slice(1,4); //"blue","yellow","black"
如果结束位置小于起始位置,则返回空数组。
如果没有传参数的话,会返回原数组的一个拷贝。
主要用途是删除项以及向数组的中部插入项。
arr.splice(start,deleteCount,item1,item2,……)
splice方法始终都会返回一个数组,该数组包含了从原始数组中删除的项,如没有删除任何项则返回一个空数组。
var colors = ["red","blue","yellow"];
var removed = colors.splice(0,1);//red
colors;//"blue","yellow"
removed = colors.splice(1,0,"black","white");//[]
colors;//"blue","black","white","yellow"
removed = colors.splice(1,1,"red","pink");//black
colors;//"blue","red","pink","white","yellow"
请注意,splice() 方法与 slice() 方法的作用是不同的,splice() 方法会直接对数组进行修改。
这两个方法都接收两个参数:
查找起点位置的索引(可选)
前者从数组开头开始查找,后者则从数组末尾开始查找。
都返回要查找的项在数组中的位置,没找到则返回-1。
在比较第一个参数和数组中的每一项时,都使用全等操作符
var numbers = [1,2,3,4,5,4,3,2,1];
numbers.indexOf(4); //3
numbers.lastIndexOf(4); //5
numbers.indexOf(4,4); //5
numbers.lastIndexOf(4,4); //3
var person = {name:"nicholas"};
var people = [{name:"nicholas"}];
var morePeople = [person];
people.indexOf(person); //-1;
morePeople.indexOf(person); //0
//这是由于person和people中的那一项并不是一个对象,因此利用全等比较会不相等,因此返回-1;
//而morePeople是由person得来,其中的那一项与person是同一个对象,因此可以找到
每一个迭代方法都对数组中的每一项运行给定函数,都接受两个参数:
1.要在每一项上运行的函数,此函数接收三个参数
2.运行该函数的作用域对象(可选)
如果函数对每一项都返回true,则返回true
如果该函数对任一项返回true,则返回true
返回该函数会返回true的项所组成的数组
无返回值
返回每次函数调用的结果组成的函数
以上这些项都不会修改数组中的值。
var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item,index,array){
return (item >2);
}); //false
var someResult = numbers.some(function(item,index,array){
return (item >2);
}); //true
var numbers = [1,2,3,4,5,4,3,2,1];
var filterResult = numbers.filter(function(item,index,array){
return (item >2);
}); //[3,4,5,4,3]
var numbers = [1,2,3,4,5,4,3,2,1];
var mapResult = numbers.map(function(item,index,array){
return item*2;
}); //[2,4,6,8,10,8,6,4,2]
从左到右(或从右到左)为每个数组元素执行一次回调函数,并把上次回调函数的返回值放在一个暂存器中传给下次回调函数,并返回最后一次回调函数的返回值。
都接收两个参数:
var total = [0, 1, 2, 3];
total.reduce(function(sum,num){
return sum+num;
},10)
这里指定了初始值10,并与数组的每一项进行相加。
copyWithin() 方法浅复制数组的一部分到同一数组中的另一个位置。
arr.copyWithin(target, start, end)
注意:start到end之间要被复制的序列会覆盖target开始的对应项,而不是插入
[1, 2, 3, 4, 5].copyWithin(2);
//[1, 2, 1, 2, 3]
//忽略了start,将从0开始;忽略了end,则复制到target位置之前
[1, 2, 3, 4, 5].copyWithin(0, 3);
//[4,5,3,4,5]
[1, 2, 3, 4, 5].copyWithin(0, 3, 4);
//[4,2,3,4,5]
这两个方法允许我们通过测试函数来获取满足条件的数组项。
function isBigEnough(element) {
return element >= 15;
}
[12, 5, 8, 130, 44].find(isBigEnough); // 130
[12, 5, 8, 130, 44].findIndex(isBigEnough); // 3
这两个方法其实是对数组中的每一项元素执行一次callback 函数,直至有一个callback返回true。当找到了这样一个元素后,该方法会立即返回这个元素的值,否则返回undefined。
这三个方法均返回一个数组的Iterator,其value分别包含数组的键名、键值以及键值对。
var arr = ["a", "b", "c"];
var iterator = arr.keys();
console.log(iterator.next()); // { value: 0, done: false }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
iterator = arr.values();
console.log(iterator.next()); // { value: a, done: false }
console.log(iterator.next()); // { value: b, done: false }
console.log(iterator.next()); // { value: c, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
iterator = arr.entries();
console.log(iterator.next().value); // [0, "a"]
console.log(iterator.next().value); // [1, "b"]
console.log(iterator.next().value); // [2, "c"]
要想知道一个数组是否包含一个值,之前只能使用indexof方法通过返回值是否为-1来判断,includes方法则会返回一个布尔值来判断一个数组是否包含一个指定的值。
let a = [1, 2, 3];
a.includes(2);
// true
a.includes(4);
// false