目录
1:数组的创建
-
字面量创建数组
let arr = [] // 创建一个空数组
console.log(arr); // []
let arr1 = [1, 2] // 创建一个包含两项数据的数组
console.log(arr1); // [1,2]
-
使用Array构造函数创建数组
// 无参数构造
let arr = new Array() // 创建一个空数组
console.log(arr); // []
// 带参数构造
1.如果只传一个数值参数,则表示创建一个初始长度为指定数值的空数组
let arr = new Array(5) // 创建一个数组长度为5的空数组
console.log(arr.length); // 5
2.如果传入一个非数值的参数或者参数个数大于 1,则表示创建一个包含指定元素的数组
let arr = new Array(1,2,3) // 创建一个包含3个数值的数组
console.log(arr); // [1,2,3]
在使用 Array 构造函数时,加不加 new 操作符,结果都一样。
-
扩展运算符创建数组
let original = [1, 2, 3];
let copy = [...original]
console.log(copy); // [1,2,3]
copy[0] = 0 // 修改copy不会法改变原数组
console.log(copy); // [0,2,3]
console.log(original); // [1,2,3]
扩展运算符可以很方便的创建一个浅拷贝的数组。
Array 静态方法
ES6 Array 新增了两个用于创建数组的静态方法: from()
和 of()
。from()
用于将类数组转换为数组,而 of()
用于将一组参数转换为数组。
-
Array.form()
从类数组对象或者可迭代对象中创建一个新的数组实例。如 Map 和 Set、Arguments 对象
// 1、从 String 生成数组
Array.from('foo');
// [ "f", "o", "o" ]
// 2、从 Set 生成数组:去重
const set = new Set(['foo', 'bar', 'baz', 'foo']);
Array.from(set);
// [ "foo", "bar", "baz" ]
//3、从 Map 生成数组
const map = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(map);
// [[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'];
//4、从 Arguments 生成数组
function arga(...args) { //...args剩余参数数组,由传递给函数的实际参数提供
let arg = Array.from(args);
console.log(arg);
}
arga('arr1', 26, 'from');
// ['arr1',26,'from']
-
Array.of()
根据一组参数来创建新的数组实例,支持任意的参数数量和类型。将按顺序成为返回数组中的元素。如果没有参数就返回一个空数组
console.log(Array.of('foo')) // ['foo']
console.log(Array.of(1)) // [1]
console.log(Array.of(1,2,3)) // [1,2,3]
console.log(Array.of({name:'fm'})) // [{ name :'fm'}]
1: 注意区别:
Array(7); // [ , , , , , , ]
Array(1, 2, 3); // [1, 2, 3]
2:数组检测
本质上,数组属于一种特殊的对象。typeof
运算符会返回数组的类型是object
。有一个经典问题是判断一个对象是不是数组,通常可以通过 instanceof
、 constructor
已经 Object.prototype.toString
来判断,但是前两这个可能不准确,后者较麻烦。为解决这个小问题,JavaScript 提供了 Array.isArray()
方法,它返回一个布尔值,表示参数是否为数组。推荐使用Array.isArray()
-
typeof 检测
//1 typeof 检测 检验结果6种,只有检测基本数据类型
typeof(['1']) // 'object'
-
instanceof 检测
// instanceof运算符用来判断一个构造函数的prototype属性所指向的对象是否存在另外一个要检测对象的原型链上
// 简单理解为:instanceof可以检测一个实例是否属于某种类型。
// eg:obj instanceof Object;//true 实例obj在不在Object构造函数中
let a = [];
a instanceof Array; // true
//在上方代码中,instanceof运算符检测Array.prototype属性是否存在于变量a的原型链上,显然a是一个数组,拥有Array.prototype属性,所以为true。
let b = {};
b instanceof Array; // false
存在问题:
1:prototype属性是可以修改的,所以并不是最初判断为true就一定永远为true
2:其次,当我们的脚本拥有多个全局环境,例如html中拥有多个iframe对象,instanceof的验证结果可能不会符合预期,例如:
//为body创建并添加一个iframe对象
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
// 获取iframe对象的构造数组方法
xArray = window.frames[0].Array;
// 通过构造函数获取一个实例
var arr = new xArray(1, 2, 3);
arr.instanceof Array; // false
-
constructor
检测
// 我们知道,实例的构造函数constructor指向构造函数,那么通过constructor属性也可以判断是否为一个数组。
let a = [1, 3, 4];
a.constructor === Array; // true
同样,这种判断也会存在多个全局环境的问题,导致的问题与instanceof相同。
// 为body创建并添加一个iframe标签
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
// 取得iframe对象的构造数组方法
xArray = window.frames[window.frames.length - 1].Array;
// 通过构造函数获取一个实例
var arr = new xArray (1, 2, 3);
arr.constructor === Array; // false
-
Object.prototype.toString.call() 检测
// Object.prototype.toString().call可以获取到对象的不同类型;就是有点麻烦
let a = [1, 2, 3];
Object.prototype.toString.call(a) === '[object Array]'; // true
// 检验是否是函数
let a = function() {};
Object.prototype.toString().call(a) === '[object Function]'; // true
// 检验是否是数字
let b = 1;
Object.prototype.toString.call(a) === '[object Number]'; // true
// 甚至对于多全局环境时,Object.prototype.toString().call()也能符合预期处理判断。
-
Array.isArray() 检测 (推荐使用)
//Array.isArray用于确定传递的值是否是一个数组,返回一个布尔值。
let a = [1, 2, 3];
Array.isArray(a); // true
//简单好用,而且对于多全局环境,Array.isArray()同样能准确判断,但有个问题,Array.isArray()是在ES5中提出的,
//也就是说ES5之前可能会存在不支持此方法的情况
//所以ES5之前不支持此方法的问题,我们其实可以做好兼容进行自行封装,像这样:
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object, Array]';
}
}
3:数组的方法
数组遍历
-
filter():过滤,数组中的每一项运行给定函数,返回满足过滤条件组成的数组 (不修改原数组)
-
forEach():循环遍历数组每一项(没有返回值)(不修改原数组)
-
map():循环遍历数组的每一项(有返回值)(不修改原数组)
增删数组项
-
push():向数组的末尾添加元素,返回值是当前数组的length (修改原数组)
-
pop():删除数组末尾的元素,返回值是被删除的元素(修改原数组)
-
shift():删除首位元素,返回值是被删除的元素(修改原数组)
-
unshift():向首位添加元素,返回值是数组的长度(修改原数组)
-
splice():对数组进行增删改(修改原数组)
查找数组项
-
indexOf():返回当前值在数组中第一次出现位置的索引 (不修改原数组)
-
lastIndexOf():返回查找的字符串最后出现的位置,如果没有找到匹配字符串则返回 -1。(不修改原数组)
-
every():判断数组中每一项是否都符合条件 (不修改原数组)
-
some():判断数组中是否存在满足的项 (不修改原数组)
-
includes():判断一个数组是否包含指定的值 (不修改原数组)
-
find(): 返回第一个匹配的值,并停止查找 (不修改原数组)
-
findIndex(): 返回第一个匹配值的索引,并停止查找 (不修改原数组)
-
entries() 、keys() 、values():遍历数组 (不修改原数组)
其他
-
join():返回值为用指定的分隔符将数组每一项拼接的字符串 (不改变原数组)
-
slice():返回数组中指定起始下标和结束下标之间的(不包含结束位置)元素组成的新数组 (不修改原数组)
-
fill():使用特定值填充数组中的一个或多个元素 (修改原数组)
-
concat():用于连接两个或多个数组 (不修改原数组)
-
sort():对数字的元素进行排序 (修改原数组)
-
reverse():对数组进行倒叙 (修改原数组)
-
copyWithin(): 从数组的指定位置拷贝元素到数组的另一个指定位置中(修改原数组)
-
toLocaleString()、toString():将数组转换为字符串 (不修改原数组)
-
flat()、flatMap():扁平化数组 (不修改原数组)
示例:
-
join():返回值为用指定的分隔符将数组每一项拼接的字符串(不改变原数组)
let arr = [1, 2, 3, 4, 5]
let arr1 = arr.join()
console.log(arr1) // 1,2,3,4,5
console.log(arr.join('-')) // 1-2-3-4-5
-
push():向数组的末尾添加元素,返回值是当前数组的length (修改原数组)
let arr = [1, 2, 3, 4, 5]
let arr1 = arr.push(6, 7)
console.log(arr1) // 7
console.log(arr) // [1, 2, 3, 4, 5, 6, 7]
-
pop():删除数组末尾的元素,返回值是被删除的元素(修改原数组)
let arr = [1, 2, 3, 4, 5]
let arr2 = arr.pop()
console.log(arr2); // 5
console.log(arr); // [1, 2, 3, 4]
-
shift():删除首位元素,返回值是被删除的元素(修改原数组)
let arr = [1, 2, 3, 4, 5]
let arr2 = arr.shift()
console.log(arr2) // 1
console.log(arr) // [2,3,4,5]
-
unshift():向首位添加元素,返回值是数组的长度(修改原数组)
let arr = [1, 2, 3, 4, 5]
let arr2 = arr.unshift(0)
console.log(arr2) // 6
console.log(arr) // [0,1,2,3,4,5]
-
slice():返回数组中指定起始下标和结束下标之间的(不包含结束位置)元素组成的新数组 ;前闭后开(不修改原数组)
let arr = [1, 2, 3, 4, 5]
// 如果只有一个参数, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项
let arr1 = arr.slice(1) // 下标从0开始
console.log(arr1) //[2, 3, 4, 5]
console.log(arr) //[1, 2, 3, 4, 5]
// 如果有两个参数,该方法返回起始和结束位置之间的项,但不包括结束位置的项
let arr2 = arr.slice(1,3)
console.log(arr2) // [2, 3]
console.log(arr) //[1, 2, 3, 4, 5]
// 当出现负数时,将负数加上数组长度的值替换该位置的数
let arr3 = arr.slice(1, -2) // 5+(-2)=3
console.log(arr3) // [2, 3]
console.log(arr) // [1, 2, 3, 4, 5]
-
splice():对数组进行增删改(修改原数组)
// 可以实现删除、插入和替换
1: 删除元素,并返回删除的元素
// 可以删除任意数量的项,只需指定 2 个参数:要删除的第一项的位置和要删除的项数。例如 splice(0,2)下标从0开始,删除两个
var arr = [1, 2, 3, 4, 5, 6];
var arrRemoved = arr.splice(0, 2);
console.log(arr); // [3, 4, 5, 6]
console.log(arrRemoved); //[1, 2]
2: 指定索引处添加元素(第二个参数为0,即指定删除数为0,就直接插入了)
// 可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、 0(要删除的项数)和要插入的项。
// 例如 splice(2,0,4,6)会从当前数组的位置 2 开始插入 4 和 6
var array1 = [1, 2, 3, 4];
array1.splice(1, 0, 6, 8); //[]
console.log(array1); // [1, 6, 8, 2, 3, 4]
3: 替换指定索引位置的元素(第二个参数不限制,即指定删除个数)
// 可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起始位置、要删除的项数和要插入的任意数量的项。
// 插入的项数不必与删除的项数相等。例如,splice (2,1,4,6)会删除当前数组位置 2 的项,然后再从位置 2 开始插入 4 和 6
let array1 = [1, 2, 3, 4];
array1.splice(1, 1, 8); //[2]
console.log(array1); // [1, 8, 3, 4]
-
fill():使用特定值填充数组中的一个或多个元素 ES6新增 (修改原数组)
//fill()方法能使用特定值填充数组中的一个或多个元素。当只是用一个参数时,该方法会用该参数的值填充整个数组。
fill(value, start, end)
//value:填充值。start:填充起始位置,可以省略。end:填充结束位置,可以省略,实际结束位置是end-1。
let arr = [1, 2, 3, 4, 5]
let arr1 = arr.fill(6);
console.log(arr1) // [6, 6, 6, 6, 6]
console.log(arr) // [6, 6, 6, 6, 6]
let arr2 = arr.fill(6, 1, 2);
console.log(arr2) // [1, 6, 3, 4, 5]
-
filter():过滤,数组中的每一项运行给定函数,返回满足过滤条件组成的数组 (不修改原数组)
let arr = [1, 2, 3, 4, 5]
let arr2 = arr.filter(function(item, index) {
return item >= 4;
})
console.log(arr2); //[4, 5]
console.log(arr); //[1, 2, 3, 4, 5]
-
concat():用于连接两个或多个数组 (不修改原数组)
let arr = [1, 2, 3, 4, 5]
let arr1 = ['a', 'b', 'c', 'd']
let arr3= arr.concat(6,arr1)
console.log(arr) // [1, 2, 3, 4, 5]
console.log(arr1) // ['a', 'b', 'c', 'd']
console.log(arr3) // [1, 2, 3, 4, 5, 6, 'a', 'b', 'c', 'd']
-
indexOf():返回当前值在数组中第一次出现位置的索引---从数组的开头(位置 0)开始向后查找。(不修改原数组)
全等比较
// indexOf(item,start) 接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。
// 在比较第一个参数与数组中的每一项时,会使用全等操作符
var arr = [1,3,5,7,7,5,3,1];
console.log(arr.indexOf(5)); //2
console.log(arr.indexOf(5,2)); //2
console.log(arr.indexOf("5"));//-1
-
lastIndexOf():返回查找的字符串最后出现的位置,如果没有找到匹配字符串则返回 -1---从数组的末尾开始向前查找。(不修改原数组)
// lastIndexOf(item,start) 接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。
var arr = [1,3,5,7,7,5,3,1];
console.log(arr.lastIndexOf(5)); //5
console.log(arr.lastIndexOf(5,4)); //2
-
every():判断数组中每一项是否都符合条件 (不修改原数组)
// 判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回 true。
let arr = [1, 2, 3, 4, 5, 6, 10, 11]
let arr2 = arr.every(function(x) {
return x < 10;
})
console.log(arr2); // false
let arr3 = arr.every(function(x) {
return x < 20;
})
console.log(arr3); // true
-
some():判断数组中是否存在满足的项 (不修改原数组)
// 判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回 true
let arr = [1, 2, 3, 4, 5, 6, 10, 11]
let arr2 = arr.some(function(x) {
return x < 10
});
console.log(arr2); // true
let arr3 = arr.some(function(x) {
return x > 20
});
console.log(arr3); // false
-
includes():判断一个数组是否包含指定的值(全等比较) es7 新增 (不修改原数组)
// includes(searchElement,fromIndex) searchElement 需要查找的元素,fromIndex 可选。从该索引处开始查找,默认为 0。
// 检测数组中是否包含一个指定的值,如果是返回true,否则false
let arr = [1, 2, 3, 4, 5, 6, 10, 11]
let arr1 = arr.includes(31);
console.log(arr1); // false
let arr2 = arr.includes(6, 3)
console.log(arr2); // true
-
sort():对数字的元素进行排序 (修改原数组)
// 对数组元素排序,没有参数时按照字母顺序(字符编码的顺序)进行排序
let arr1 = ["a", "d", "c", "b"];
console.log(arr1.sort()); // ["a", "b", "c", "d"]
let arr2 = [13, 24, 51, 3];
console.log(arr2.sort()); // [13, 24, 3, 51]
console.log(arr2); // [13, 24, 3, 51](原数组被改变)
array.sort(compareFunction)可以通过提供“比较函数”来排序,该函数应返回负值、零值或正值,具体取决于参数,例如:function(a, b){return a-b}。如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。
function compare(value1, value2) {
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
}
let arr8 = [13, 24, 51, 3];
console.log(arr8.sort(compare)); //[3, 13, 24, 51]
如果需要通过比较函数产生降序排序的结果,只要交换比较函数返回的值即可:
function compare(value1, value2) {
if (value1 < value2) {
return 1;
} else if (value1 > value2) {
return -1;
} else {
return 0;
}
}
let arr2 = [13, 24, 51, 3];
console.log(arr2.sort(compare)); // [51, 24, 13, 3]
-
reverse():对数组进行倒叙 (修改原数组)
// 用于颠倒数组中元素的顺序
let arr = [13, 24, 51, 3];
console.log(arr.reverse()); //[3, 51, 24, 13]
console.log(arr); //[3, 51, 24, 13](原数组改变)
-
forEach():循环遍历数组每一项(没有返回值) (不修改原数组)
// function(currentValue, index, arr) 必需。为数组中的每个元素运行的函数。
//参数分别为:遍历的数组内容;第对应的数组索引,数组本身
let arr = [1, 2, 3, 4]
arr.forEach((item,index,ar) => {
console.log(item + '|' + index + '|' + (ar === arr))
})
// 1|0|true
// 2|1|true
// 3|2|true
// 4|3|true
-
map():循环遍历数组的每一项(有返回值) (不修改原数组)
// 对数组中的每一项运行给定函数并返回处理后的数组,不会改变原数组
let arr = [1, 2, 3, 4, 5, 6, 10, 11]
let arr2 = arr.map(function(item){
return item + 1
});
console.log(arr2) // [2, 3, 4, 5, 6, 7, 11, 12]
console.log(arr) // [1, 2, 3, 4, 5, 6, 10, 11]
-
copyWithin(): 从数组的指定位置拷贝元素到数组的另一个指定位置中 )[es6 新增] (修改原数组)
待补充
-
find(): 返回第一个匹配的值,并停止查找 (不修改原数组)
// find()方法接受两个参数:一个回调函数,一个可选值用于指定回调函数内部的 this。
// 该回调函数可接受三个参数:数组的某个元素,该元素对应的索引位置,以及该数组本身。
// find()方法会在回调函数第一次返回 true 时停止查找。
let arr = [1, 2, 3, 5, 1, 9];
console.log(arr.find((item, index, arr) => {
return item > 2;
})); // 3 返回匹配的值
-
findIndex(): 返回第一个匹配值的索引,并停止查找 (不修改原数组)
// findIndex()方法接受两个参数:一个回调函数,一个可选值用于指定回调函数内部的 this。
// 该回调函数可接受三个参数:数组的某个元素,该元素对应的索引位置,以及该数组本身。
// findIndex()方法会在回调函数第一次返回 true 时停止查找。
let arr = [1, 2, 3, 5, 1, 9];
console.log(arr.findIndex((item, index, arr) => {
return item > 2;
})); // 2 返回匹配位置的索引
-
toLocaleString()、toString():将数组转换为字符串 (不修
let arr = ['1','2']
arr.toLocaleString() // '1,2'
arr.toString() // '1,2'
// toLocaleString()方法,主要用于将Date对象转换为本地格式的字符串
var date = new Date();
console.log(date.toString()) // 'Tue Jun 13 2023 15:09:29 GMT+0800 (中国标准时间)'
console.log(date.toLocaleString('zh')); // 2023/6/13 15:10:21
console.log(date.toLocaleString('en')); // 6/13/2023, 3:10:21 PM
-
flat():扁平化数组 (不修改原数组)
// flat()返回一个扁平化的数组
// 参数: 指定要提取嵌套数组的结构深度,使用Infinity,可展开任意深度的嵌套数组,默认值为 1
let arr = [0, 1, 2, [3, 4]]
let arr1 = arr.flat()
console.log(arr) // [0, 1, 2, [3, 4]]
console.log(arr1) // [0, 1, 2, 3, 4]
let arr2 = [0, 1, 2, [[[3, 4]]]]
let arr3 = arr2.flat(2)
console.log(arr3) // [0, 1, 2, [3, 4]]
let arr4 = arr2.flat(Infinity)
console.log(arr4)// [0, 1, 2, 3, 4]
// 如果原数组有空项,flat()方法会跳过空项
let arr5 = [1, 2, , 4, 5];
let arr6 = arr5.flat();
console.log(arr6) // [1, 2, 4, 5]
-
flatMap():map() 方法后跟深度为 1 的 flat() 方法的组合 (不修改原数组)
// flatMap()对数组的每个成员执行函数,相当于执行Array.prototype.map(),然后对返回值组成的数组执行flat()方法。
[2, 3, 4].flatMap((x) => [x, x * 2])
// [2, 4, 3, 6, 4, 8]
1. 先执行map // [[2,4],[3,6],[4,8]]
2. 在执行flat // [[2,4],[3,6],[4,8]].flat() // [2, 4, 3, 6, 4, 8]
-
entries() 、keys() 、values():遍历数组 [es6 新增] (不修改原数组)
// entries(),keys()和values() —— 用于遍历数组。它们都返回一个遍历器对象,可以用for...of循环进行遍历
// 区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历
let arr = ['a', 'b', 'c', 'd']
for (let index of arr.keys()) {
console.log(index)
}
// 0
// 1
// 2
// 3
for (let item of arr.values()) {
console.log(item)
}
// a
// b
// c
// d
for (let [index, item] of arr.entries()) {
console.log(index, item)
}
// 0 "a"
// 1 "b"
// 3 "c"
// 4 "d"
参考链接:
https://zhuanlan.zhihu.com/p/584291210