除了 Object
之外,Array
类型恐怕是 ECMAScript
中最常用的类型了;数组的每一项可以保存任何类型的数据;数组的大小是可以动态调整的,即可以随着数据的添加自动增长以容纳新增数据。
下面是操作数组的常用方法:
(一)数组的创建
(二)数组自带属性
(三)检测是否为数组
(四)数组元素的增加与删除
(五)数组与字符串的相互转化
(六)数组的截取和合并
(七)数组元素的排序
(八)元素在数组中的位置
(九)数组的遍历与迭代
(十)其他方法
(十一)扩展运算符
(一)数组的创建
- 使用
Array
构造函数的方式
new Array(); // 创建一个数组
new Array([size]); // 创建一个数组并指定长度,注意不是上限,是长度
new Array(element0, element1, ..., elementn); // 创建一个数组并赋值
const array = new Array();
array[0] = '1';
- 采用字面量的方法
const array = []; //创建一个空数组
const array2 = [1, 2, 3]; //创建一个有三个元素的数组
在使用数组字面量表示法时,不会调用Array
构造函数。
(二)数组自带属性
constructor // 返回创建数组对象的原型函数
length // 返回数组对象的长度
prototype // 可以增加数组的原型方法和属性
关于数组的length
属性
(1)关于数组的的length
属性,这个属性不是只读的,数组的该属性可读可写;通过设置这个属性,可以从数组的末尾移除项或向数组中添加新项。
// 将其 length 属性设置为 2 会移除最后一项结果再访问 colors[2]就会显示 undefined 了
var colors = ["red", "blue", "green"]; // 创建一个包含 3 个字符串的数组
colors.length = 2;
alert(colors[2]); //undefined
(2)如果将其 length
属性设置为大于数组 项数的值,则新增的每一项都会取得undefined
值。
var colors = ["red", "blue", "green"]; // 创建一个包含 3 个字符串的数组
colors.length = 4;
alert(colors[3]); //undefined
(3)利用 length
属性可以方便地在数组末尾添加新项。
var colors = ["red", "blue", "green"]; // 创建一个包含 3 个字符串的数组
colors[colors.length] = "black"; //(在位置 3)添加一种颜色
colors[colors.length] = "brown"; //(在位置 4)再添加一种颜色
(三)检测是否为数组
- 使用
instanceof
方法
instanceof
用于判断一个变量是否是某个对象的实例
const array = new Array();
array instanceof Array; //true
- 使用
constructor
属性
constructor
属性返回对创建此对象的数组函数的引用,就是返回对象相对应的构造函数。
const array = new Array();
array.constructor === Array; // true
- 使用
isArray()
方法
对支持isArray
的浏览器,直接使用isArray
方法。
const array = new Array();
Array.isArray(array); //true
如果浏览器不支持Array.isArray()
则需进行必要判断。
/**
* 判断一个对象是否是数组,参数不是对象或者不是数组,返回false
*
* @param {Object} arg 需要测试是否为数组的对象
* @return {Boolean} 传入参数是数组返回true,否则返回false
*/
function isArray(arg) {
if (typeof arg === 'object') {
return Object.prototype.toString.call(arg) === '[object Array]';
}
return false;
}
(四)数组元素的增加与删除
array.push(e1, e2, ...eN)
将一个或多个元素添加到数组的末尾,并返回新数组的长度。
const array = [1, 2, 3];
const length = array.push(4, 5);
// array: [1, 2, 3, 4, 5]; length: 5
array.unshift(e1, e2, ...eN)
将一个或多个元素添加到数组的开头,并返回新数组的长度。
const array = [1, 2, 3];
const length = array.unshift(4, 5);
// array: [ 4, 5, 1, 2, 3]; length: 5
array.pop()
从数组中删除最后一个元素,并返回最后一个元素的值,原数组的最后一个元素被删除。数组为空时返回undefined
。
const array = [1, 2, 3];
const poped = array.pop();
// array: [1, 2]; poped: 3
array.shift()
删除数组的第一个元素,并返回第一个元素,原数组的第一个元素被删除。数组为空时返回undefined
。
const array = [1, 2, 3];
const shifted = array.shift();
// array: [2, 3]; shifted: 1
array.splice(start[, deleteCount, item1, item2, ...])
从数组中添加/删除元素,返回值是由被删除的元素组成的一个新的数组,如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。
start
指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从1计数)。deleteCount
(可选),从start
位置开始要删除的元素个数。如果deleteCount
是 0,则不移除元素。这种情况下,至少应添加一个新元素。如果deleteCount
大于start
之后的元素的总数,则从start
后面的元素都将被删除(含第start
位)。item1, item2, …
(可选),要添加进数组的元素,从start
位置开始。如果不指定,则splice()
将只删除数组元素。
const array = [1, 2, 3, 4, 5];
const deleted = array.splice(2, 0, 6); // 在索引为2的位置插入6
// array 变为 [1, 2, 6, 3, 4, 5]; deleted为[]
(五)数组与字符串的相互转化
- 数组转字符串
array.join(separator=',')
将数组中的元素通过separator
连接成字符串,并返回该字符串,separator默认为","。
const array = [1, 2, 3];
let str = array.join(',');
// str: "1,2,3"
toLocaleString()
、toString()
、valueOf()
:所有对象都具有这三个方法,数组继承的这个三个方法,可以看作是join()
的特殊用法,不常用。
var colors = ["red", "blue", "green"];
// 调用数组的 toString()方法会返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串
console.log(colors.toString()); // red,blue,green
// 调用 valueOf()返回的还是数组
console.log(colors.valueOf()); // ["red", "blue", "green"]
console.log(colors.toLocaleString()); // red,blue,green
如果数组中的某一项的值是 null
或者 undefined
,那么该值在join()
、 toLocaleString()
、toString()
和 valueOf()
方法返回的结果中以空字符串表示。
- 字符串转数组
string.split(separator,howmany)
用于把一个字符串分割成字符串数组。separator
(必需),字符串或正则表达式,从该参数指定的地方对字符串进行分割。howmany
(可选),该参数可指定返回的数组的最大长度。
let str = "abc,abcd,aaa";
let array = str.split(",");// 在每个逗号(,)处进行分解。
// array: [abc,abcd,aaa]
const array1 = "helloworld";
let str1 = array1.split('');
//["h", "e", "l", "l", "o", "w", "o", "r", "l", "d"]
(六)数组的截取和合并
- 数组的截取
array.slice(start, end)
方法
slice()
通过索引位置,从数组中返回start
下标开始,直到end
下标结束(不包括)的新数组,该方法不会修改原数组,只是返回一个新的子数组。
start
(必填),设定新数组的起始位置(下标从0开始算起);如果是负数,则表示从数组尾部开始算起(-1 指最后一个元素,-2 指倒数第二个元素,以此类推)。end
(可选),设定新数组的结束位置;如果不填写该参数,默认到数组结尾;如果是负数,则表示从数组尾部开始算起(-1 指最后一个元素,-2
指倒数第二个元素,以此类推)。
// 获取仅包含最后一个元素的子数组
let array = [1,2,3,4,5];
array.slice(-1); // [5]
// 获取不包含最后一个元素的子数组
let array2 = [1,2,3,4,5];
array2.slice(0, -1); // [1,2,3,4]
该方法并不会修改数组,而是返回一个子数组。如果想删除数组中的一段元素,应该使用方法 array.splice()
。
- 数组的合并 -
array.concat([item1[, item2[, . . . [,itemN]]]])
方法
conact()
是将多个数组(也可以是字符串,或者是数组和字符串的混合)连接为一个数组,返回连接好的新的数组。
const array = [1,2].concat(['a', 'b'], ['name']);
// [1, 2, "a", "b", "name"]
(七)数组元素的排序
array.sort()
方法
sort()
方法用于对数组的元素进行排序,并返回原数组。如果不带参数,按照字符串UniCode
码的顺序进行排序。
const array = ['a', 'd', 'c', 'b'];
array.sort(); //['a', 'b', 'c', 'd']
为sort()
中传入排序规则函数可实现自定义排序。
排序函数规则:(1)传两个形参;(2)当返回值为正数时,交换传入两形参在数组中位置。
按照数值大小进行排序-升序
[1, 8, 5].sort((a, b) => {
return a-b; // 从小到大排序
});
// [1, 5, 8]
按照数值大小进行排序-降序
[1, 8, 5].sort((a, b) => {
return b-a; // 从大到小排序
});
// [8, 5, 1]
array.reverse()
方法reverse()
方法将数组中元素的位置颠倒,第一个数组元素成为最后一个数组元素,最后一个数组元素成为第一个。在原数组上操作,然后返回原数组。
let arr = [1,2,3,4,5]
console.log(arr.reverse()) // [5,4,3,2,1]
console.log(arr) // [5,4,3,2,1]
数组的sort()
和reverse()
方法都对原数组进行了修改,返回值是经过排序之后的数组。
(八)元素在数组中的位置
indexOf()
与lastIndexOf()
indexOf(searchElement[, fromIndex = 0])
方法返回某个指定的字符串值在字符串中首次出现的位置。lastIndexOf(searchElement[, fromIndex = 0])
方法返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。- 这两个方法都接受两个参数:
searchElement
:要查找的元素;fromIndex
:开始查找的索引位置。- 这两个方法都返回查找的项在数组中的位置,或者在没找到的情况下返回-1。
[2, 9, 7, 8, 9].indexOf(9); // 1
[2, 9, 7, 8, 9].lastIndexOf(9); // 4
find()
与findIndex()
(1) find(callback[, thisArg])
方法,用于找出第一个符合条件的数组元素。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined
。
[1, 4, -5, 10].find((n) => n < 0)
// -5
find()
方法的回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。
[1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
}) // 10
(2) findIndex(callback[, thisArg])
返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
[1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;
}) // 2
这两个方法都可以接受第二个参数,用来绑定回调函数的this
对象。
function f(v){
return v > this.age;
}
let person = {name: 'John', age: 20};
[10, 12, 26, 15].find(f, person); // 26
includes(searchElement[, fromIndex = 0])
方法返回一个布尔值,表示某个数组是否包含给定的值。
这个方法都接受两个参数:searchElement
:要查找的元素;fromIndex
:开始查找的索引位置。
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
(九)数组的遍历与迭代
array.filter(callback, thisArg)
方法使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组。
参数说明:
callback
用来测试数组的每个元素的函数,返回true
表示保留该元素(通过测试),false
则不保留。thisArg
可选。执行callback
时的用于this
的值。
// callback定义如下,三个参数: element:当前元素值;index:当前元素下标; array:当前数组
function callback(element, index, array) {
// callback函数必须返回true或者false,返回true保留该元素,false则不保留。
return true || false;
}
const filtered = [1, 2, 3].filter(element => element > 1);
// filtered: [2, 3];
array.every(callback[, thisArg])
方法检测数组中的每一个元素是否都通过了callback
测试,全部通过返回true
,否则返回false
。
// callback定义如下: element:当前元素值;index:当前元素下标; array:当前数组
function callback(element, index, array) {
// callback函数必须返回true或者false告知every是否通过测试
return true || false;
}
let a = [1, 2, 3, 4, 5];
let b = a.every((item) => {
return item > 0;
});
let c = a.every((item) => {
return item > 1;
});
console.log(b); // true
console.log(c); // false
array.some(callback[, thisArg])
判断数组中是否包含可以通过callback
测试的元素,与every
不同的是,这里只要某一个元素通过测试,即返回true
。callback
定义同上。
[2, 5, 8, 1, 4].some(item => item > 6);
// true
array.map(callback[, thisArg])
方法返回一个由原数组中的每个元素调用callback
函数后的返回值组成的新数组。
let a = [1, 2, 3, 4, 5];
let b = a.filter((item) => {
return item > 3;
});
console.log(b); // [4 ,5]
let bb = [];
a.map((item) => {
if (item > 3) {
bb.push(item);
}
});
console.log(bb); // [4, 5]
let bbb = a.map((item) => {
return item + 1;
});
console.log(bbb); // [2, 3, 4, 5, 6]
array.forEach(callbak)
为数组的每个元素执行对应的方法。
// callback定义如下: element:当前元素值;index:当前元素下标; array:当前数组
let a = [1, 2, 3, 4, 5];
let b = [];
a.forEach((item) => {
b.push(item + 1);
});
console.log(b); // [2,3,4,5,6]
- 遍历数组的方法:
entries()
、values()
、keys()
这三个方法都是返回一个遍历器对象,可用for...of
循环遍历,唯一区别:keys()
是对键名的遍历、values()
对键值的遍历、entries()
是对键值对的遍历。
for(let item of ['a','b'].keys()){
consloe.log(item);
//0
//1
}
for(let item of ['a','b'].values()){
consloe.log(item);
//'a'
//'b'
}
let arr4 = [0,1];
for(let item of arr4.entries()){
console.log(item);
// [0, 0]
// [1, 1]
}
for(let [index,item] of arr4.entries()){
console.log(index+':'+item);
//0:0
//1:1
}
array.reduce(callback[, initialValue])
方法返回针对数组每项调用callback
函数后产生的累积值。
const total = [0, 1, 2, 3].reduce((sum, value) => {
return sum + value;
}, 0);
// total is 6
const flattened = [[0, 1], [2, 3], [4, 5]].reduce((a, b) => {
return a.concat(b);
}, []);
// flattened is [0, 1, 2, 3, 4, 5]
参数说明:initialValue
:累加器初始值, callback
函数定义如下:
function callback(accumulator, currentValue, currentIndex, array) {
}
以上callback
的参数中accumulator
代表累加器的值,初始化时,如果initialValue
有值,则accumulator
初始化的值为initialValue
,整个循环从第一个元素开始;initialValue
无值,则accumulator
初始化的值为数组第一个元素的值,currentValue
为数组第二个元素的值,整个循环从第二个元素开始。initialValue
的数据类型可以是任意类型,不需要跟原数组内的元素值类型一致。
const newArray = [{ name: 'aa', age: 1 }, { name: 'bb', age: 2 }, { name: 'cc', age: 3 }].reduce((arr, element) => {
if (element.age >= 2) {
arr.push(element.name);
}
return arr;
// 必须有return,因为return的返回值会被赋给新的累加器,否则累加器的值会为undefined。
}, []);
// newArray is ["bb", "cc"];
// 上面代码的同等写法:
const newArray = [{ name: 'aa', age: 1 }, { name: 'bb', age: 2 }, { name: 'cc', age: 3 }].filter(element => element.age >= 2).map(item => item.name);
// newArray is ["bb", "cc"];
(十)其他方法
Array.from()
方法
Array.from()
方法是用于将类似数组的对象(即有length属性的对象)和可遍历对象转为真正的数组。
比如,使用·Array.from()·方法,可以轻松将·JSON·数组格式转为数组。
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
Array.of()
方法
Array.of()
方法是将一组值转变为数组。
let arr0 = Array.of(1,2,33,5);
console.log(arr0);//[1,2,33,5]
let arr1 = Array.of('你好','hello');
console.log(arr1);//["你好", "hello"]
(十一)扩展运算符
扩展运算符(spread
)是三个点(...
)。它好比rest
参数的逆运算,将一个数组转为用逗号分隔的参数序列。
console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
该运算符主要用于函数调用。
function add(x, y) {
return x + y;
}
const numbers = [4, 38];
add(...numbers) // 42
注意,扩展运算符如果放在括号中,JavaScript
引擎就会认为这是函数调用,就会报错。
(...[1,2])
// Uncaught SyntaxError: Unexpected number
console.log((...[1,2]))
// Uncaught SyntaxError: Unexpected number
console.log(...[1, 2])
// 1,2