使用数组直接量创建数组,推荐使用这种方式,性能更高
var arr1 = []
var arr2 = [1, 3, 45]
var arr3 = [1, 'aa', true,] // 有三个不同数据类型的数组,最后一个逗号为结尾的逗号
调用构造函数Array()创建数组 不推荐使用这种方式
var a = new Array() // [] 调用时没有参数
var b = new Array(10) // 调用时有一个数值参数,它指定长度
var c = new Array(1, 2, 3) // [1, 2, 3] 显式指定两个或多个数组元素或者数组的一个非数值元素
var d = new Array('22') // ['22'] 如果传入一个非数值的参数或者参数个数大于1,则表示创建一个包含指定元素的数组
数组元素的读和写
使用[]操作符来访问数组中的一个元素
var c = [0, , 2]
console.log(c[0]) // 0
console.log(c[1]) // undefined
console.log(c[2]) // 2
console.log(c[3]) // undefined
c[1] = 3
console.log(c) // [0, 3, 2]
c[5] = 6
console.log(c) // [0, 3, 2, empty × 2, 6]
数组的长度
每个数组都有一个 length 属性,针对非稀疏数组,length 属性值代表数组中元素的个数,其值比数组中最大的索引大一。当数组是稀疏时,length 属性值会大于元素个数。数组的长度会大于每一个元素的索引值。
var c = [0, , 2]
c.length // =>3 稀疏数组,最大索引值为2,数组长度为3
设置 length 属性为一个小于当前数组长度的非负整数 n 时,当前数组中的那些索引值大于等于 n 的元素将从数组中删除。同时可以将 length 属性设置为大于当前长度的值,实际不会像数组中添加元素,它只是在数组尾部创建一个空的区域。
数组也是对象
数组通过数字进行索引,但有趣的是它们也是对象,所以也可以包含字符串键值和属性 (但这些并不计算在数组长度内)
var a = []
a[0] = 1
a['foobar'] = 2
console.log(a) // [1, foobar: 2]
console.log(a.length) // 1
console.log(a['foobar']) // 2
console.log(a[0]) // 1
console.log(a[1]) // undefined
这里有个问题需要特别注意,如果字符串键值能够被强制类型转换为十进制数字的话,它就会被当作数字索引来处理。
var a = []
a['13'] = 42
a.length // 14
删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined
var a = [1, 2, 3, 4, 5];
var b = a.shift();
// a:[2, 3, 4, 5] b:1
将参数添加到原数组开头,并返回数组的长度
var a = [1, 2, 3, 4, 5];
var b = a.unshift(-2, -1);
//a:[-2, -1, 1, 2, 3, 4, 5] b:7
删除原数组最后一项,并返回删除元素的值;如果数组为空则返回undefined
var a = [1, 2, 3, 4, 5];
var b = a.pop();
// a:[1, 2, 3, 4] b:5
将参数添加到原数组末尾,并返回数组的长度
var a = [1, 2, 3, 4, 5];
var b = a.push(6, 7);
// a:[1, 2, 3, 4, 5, 6, 7] b:7
将多个数组拼接成一个数组 拼接后数组的元素将按照传入参数的顺序排序 ,不改变原数组,返回拼接后的数组
var array = [1, 2];
var newArray = array.concat([3, 4], "a", true);
console.log(array); // [1, 2]
console.log(newArray); // [1, 2, 3, 4, "a", true]
从start位置开始删除deleteCount项,并从该位置起插入val1, val2,...
splice()方法始终都会返回一个数组,该数组中包含从原始数组中删除的项,如果没有删除任何项,则返回一个空数组
var a = [1, 2, 3, 4, 5];
var b = a.splice(2, 2, 7, 8, 9); //a:[1, 2, 7, 8, 9, 5] b:[3, 4]
var b = a.splice(0, 1); // 同shift
a.splice(0, 0, -2, -1); var b = a.length; // 同unshift
var b = a.splice(a.length-1, 1); // 同pop
a.splice(a.length, 0, 6, 7); var b = a.length; // 同push
将数组反序
var a = [1, 2, 3, 4, 5];
var b = a.reverse();
// a:[5, 4, 3, 2, 1] b:[5, 4, 3, 2, 1]
返回从原数组中指定开始下标到结束下标之间的项组成的新数组。在只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。当出现负数时,将负数加上数组长度的值来替换该位置的数(原数组中的倒数第几个元素开始提取),slice(-2)
表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。
var a = [1, 2, 3, 4, 5];
var b = a.slice(2, 5);
// a:[1, 2, 3, 4, 5]; b:[3, 4, 5]
slice 方法可以用来将一个类数组(Array-like)对象/集合转换成一个新数组。你只需将该方法绑定到这个对象上。 一个函数中的arguments就是一个类数组对象的例子
function zxxFn () {
return Array.prototype.slice.call(arguments);
}
var zxx = zxxFn(1, 2, 3);
console.log(zxx) // [1, 2, 3]
除了使用 Array.prototype.slice.call(
arguments
)
,你也可以简单的使用 [].slice.call(arguments)
来代替。另外,你可以使用 bind
来简化该过程。
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.call.bind(unboundSlice);
function zxxFn() {
return slice(arguments);
}
var zxx = zxxFn(1, 2, 3);
console.log(zxx) // [1, 2, 3]
将数组的元素组起一个字符串,以separator为分隔符,省略的话则用默认用逗号为分隔符
var a = [1, 2, 3, 4, 5];
var b = a.join("|");
// a:[1, 2, 3, 4, 5] b:"1|2|3|4|5"
按升序排列数组项——即最小的值位于最前面,最大的值排在最后面
在排序时,sort()方法会调用每个数组项的 toString()转型方法,然后比较得到的字符串,以确定如何排序。即使数组中的每一项都是数值, sort()方法比较的也是字符串,因此会出现以下的这种情况
var arr1 = ["a", "d", "c", "b"];
console.log(arr1.sort()); // ["a", "b", "c", "d"]
arr2 = [13, 24, 51, 3];
console.log(arr2.sort()); // [13, 24, 3, 51]
console.log(arr2); // [13, 24, 3, 51](元数组被改变)
为了解决上述问题,sort()方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。以下就是一个简单的比较函数:
function compare(value1, value2) {
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [3, 13, 24, 51]
如果需要通过比较函数产生降序排序的结果,只要交换比较函数返回的值即可:
function compare(value1, value2) {
if (value1 < value2) {
return 1;
} else if (value1 > value2) {
return -1;
} else {
return 0;
}
}
arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [51, 24, 13, 3]
indexOf():接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找。
lastIndexOf:接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的末尾开始向前查找。
这两个方法都返回要查找的项在数组中的位置,或者在没找到的情况下返回-1。在比较第一个参数与数组中的每一项时,会使用全等操作符。
var array = [1, 2, 3, 4, 5];
var ret = array.indexOf(4);
console.log(array); // [1, 2, 3, 4, 5]
console.log(ret); // 3
console.log(array.indexOf(6)); // -1
console.log(array.lastIndexOf(8)); // -1
console.log(array.lastIndexOf(5)); // 4
浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。
target
:0 为基底的索引,复制序列到该位置。如果是负数,target
将从末尾开始计算。target
大于等于 arr.length
,将会不发生拷贝。如果 target
在 start
之后,复制的序列将被修改以符合 arr.length
。start
:0 为基底的索引,开始复制元素的起始位置。start
被忽略,copyWithin
将会从0开始复制。end
:0 为基底的索引,开始复制元素的结束位置。copyWithin
将会拷贝到该位置,但不包括 end
这个位置的元素。end
被忽略,copyWithin
方法将会一直复制至数组结尾(默认为 arr.length
)。let numbers = [1, 2, 3, 4, 5];
numbers.copyWithin(-2);
// [1, 2, 3, 1, 2]
numbers.copyWithin(0, 3);
// [4, 5, 3, 4, 5]
numbers.copyWithin(0, 3, 4);
// [4, 2, 3, 4, 5]
numbers.copyWithin(-2, -3, -1);
// [1, 2, 3, 3, 4]
[].copyWithin.call({length: 5, 3: 1}, 0, 3);
// {0: 1, 3: 1, length: 5}
// ES2015 Typed Arrays are subclasses of Array
var i32a = new Int32Array([1, 2, 3, 4, 5]);
i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]
// On platforms that are not yet ES2015 compliant:
[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
// Int32Array [4, 2, 3, 4, 5]
value:
用来填充数组元素的值。start
:可选,起始索引,默认值为0。end
:可选,终止索引,默认值为 this.length
。start
是个负数, 则开始索引会被自动计算成为 length+start
, 其中 length
是 this
对象的 length
属性值。如果 end
是个负数, 则结束索引会被自动计算成为 length+end
。[1, 2, 3].fill(4); // [4, 4, 4]
[1, 2, 3].fill(4, 1); // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2); // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1); // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3); // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2); // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN); // [1, 2, 3]
[1, 2, 3].fill(4, 3, 5); // [1, 2, 3]
Array(3).fill(4); // [4, 4, 4]
[].fill.call({ length: 3 }, 4); // {0: 4, 1: 4, 2: 4, length: 3}
// Objects by reference.
var arr = Array(3).fill({}) // [{}, {}, {}];
// 需要注意如果fill的参数为引用类型,会导致都执行都一个引用类型
// 如 arr[0] === arr[1] 为true
arr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]
valueToFind
:需要查找的元素值。fromIndex
:可选,从fromIndex
索引处开始查找 valueToFind
。如果为负值,则按升序从 array.length + fromIndex
的索引开始搜 (即使从末尾开始往前跳 fromIndex
的绝对值个索引,然后往后搜寻)。默认为 0。[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true
var arr = ['a', 'b', 'c'];
arr.includes('a', -100); // true
arr.includes('b', -100); // true
arr.includes('c', -100); // true
arr.includes('a', -2); // false
作为通用方法的 includes()
(function() {
console.log([].includes.call(arguments, 'a')); // true
console.log([].includes.call(arguments, 'd')); // false
})('a','b','c');
返回一个包含数组中每个索引键的Array Iterator对象。索引迭代器会包含那些没有对应元素的索引
var arr = ["a", , "c"];
var sparseKeys = Object.keys(arr);
console.log(sparseKeys); // ['0', '2']
[...arr1.entries()] // [[0, "a"][1, undefined][2, "c"]]
[...arr1.keys()] // [0, 1, 2]
[...arr1.values()] // ["a", undefined, "c"]
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var arr2 = arr.filter(function(x, index) {
return index % 3 === 0 || x >= 8;
});
console.log(arr2); //[1, 4, 7, 8, 9, 10]
var arr = [1 , 3, 4, 7, 12]
var arrTest = arr.filter((item, index, array) => {
console.log('当前值:' + item, '当前值的索引' + index, '当前数组' + array)
return item >= 4
})
console.log(arrTest)
every():判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true。
var arr = [1, 2, 3, 4, 5];
var arr2 = arr.every(function(x) {
return x < 10;
});
console.log(arr2); //true
var arr3 = arr.every(function(x) {
return x < 3;
});
console.log(arr3); // false
var arr = [1 , 3, 4, 7, 12]
var arrTest = arr.every((item, index, array) => {
console.log('当前值:' + item, '当前值的索引' + index, '当前数组' + array)
return item > 0
})
console.log(arrTest)
some():判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true。
var arr = [1, 2, 3, 4, 5];
var arr2 = arr.some(function(x) {
return x < 3;
});
console.log(arr2); //true
var arr3 = arr.some(function(x) {
return x < 1;
});
console.log(arr3); // false
将伪数组对象(拥有一个 length
属性和若干索引属性的任意对象)或迭代对象(可以获取对象中的元素,如 Map和 Set 等)转化成真数组,返回值:一个新的数组
Array.from(arrayLike, mapFn, thisArg)
arrayLike
想要转换成数组的伪数组对象或可迭代对象。mapFn (可选参数)
如果指定了该参数,新数组中的每个元素会执行该回调函数。thisArg (可选参数)
可选参数,执行回调函数 mapFn
时 this
对象。Array.from('foo');
// ["f", "o", "o"]
=====
let s = new Set(['foo', window]);
Array.from(s);
// ["foo", window]
=====
let m = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(m);
// [[1, 2], [2, 4], [4, 8]]
const mapper = new Map([['1', 'a'], ['2', 'b']]);
Array.from(mapper.values());
// ['a', 'b'];
Array.from(mapper.keys());
// ['1', '2'];
=====
function f() {
return Array.from(arguments);
}
f(1, 2, 3); // [1, 2, 3]
=====
Array.from([1, 2, 3], x => x + x);
// x => x + x代表这是一个函数,只是省略了其他的定义,这是一种Lambda表达式的写法
// 箭头的意思表示从当前数组中取出一个值,然后自加,并将返回的结果添加到新数组中
// [2, 4, 6]
Array.from({length: 5}, (v, i) => i);
// [0, 1, 2, 3, 4]
数组去重合并
function combine(){
let arr = [].concat.apply([], arguments); //没有去重复的新数组
return Array.from(new Set(arr));
}
var m = [1, 2, 2], n = [2,3,3];
console.log(combine(m,n)); // [1, 2, 3]
Array.of()
Array.of()
和 Array
构造函数之间的区别在于处理整数参数:Array.of(7)
创建一个具有单个元素 7 的数组,而 Array(7)
创建一个长度为7的空数组(注意:这是指一个有7个空位(empty)的数组,而不是由7个undefined
组成的数组)Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array.of(undefined); // [undefined]
Array(7); // [ , , , , , , ]
Array(1, 2, 3); // [1, 2, 3]
用于确定传递的值是否是一个 Array。
// 下面的函数调用都返回 true
Array.isArray([]);
Array.isArray([1]);
Array.isArray(new Array());
Array.isArray(new Array('a', 'b', 'c', 'd'))
// 鲜为人知的事实:其实 Array.prototype 也是一个数组。
Array.isArray(Array.prototype);
// 下面的函数调用都返回 false
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(17);
Array.isArray('Array');
Array.isArray(true);
Array.isArray(false);
Array.isArray(new Uint8Array(32))
Array.isArray({ __proto__: Array.prototype });
当检测Array实例时, Array.isArray 优于 instanceof,因为Array.isArray能检测iframes.
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]
// Correctly checking for Array
Array.isArray(arr); // true
// Considered harmful, because doesn't work though iframes
arr instanceof Array; // false