一、数组创建方式
1、字面量创建方式
var arr = ['a', 'b', 'c',....]
2、new创建方式
var arr = new Array('a', 'b', 'c',.....)
或
var arr = new Array(数组长度)
二、数组相关方法
1、push()
-
数组末尾添加一个或多个元素
-
其返回值是返回当前数组改变后的新的长度
let arr = [1,2,3];
let len = arr.push(4,5,6);
console.log(arr); // [1,2,3,4,5,6] 改变了原数组
console.log(len); // 6 返回新数组的长度
2、pop()
- 删除数组中的最后一位并返回删除的值(不能删除多个)
- 如果是空数组则返回值是undefined
let arr = [1,2,3];
let value = arr.pop();
console.log(arr); // [1,2] 改变了原数组
console.log(value); // 3 返回被删除的元素
let arr2 = [];
console.log(arr2.pop()); //undefined 空数组返回undefined
3、unshift()
- 向数组开头添加一个或多个元素
- 返回值是新数组的长度
let arr = [1,2,3];
let len2 = arr.unshift(7,8,9);
console.log(arr); // [7, 8, 9, 1, 2, 3]
console.log(len2); // 6 返回新数组的长度
4、shift()
- 删除数组中的第一位并返回删除的值(不能删除多个)
- 如果是空数组则返回值是undefined
let arr = [1,2,3];
let arr2 = [];
console.log(arr2.shift()); //undefined
console.log(arr.shift()); // 1
console.log(arr); // [2,3] 改变了原数组
5、splice()
可以利用splice进行数组的删除、替换、添加
splice(start[,num, item1,item2...])
- 删除
-
start 删除的起始位置(删除所有从该位置往后的元素,包含该位置,不传递start则不删除元素)
- 如果start过大,超过原数组长度,则不会删除元素
- 如果start = 0 ,则将数组中所有元素删除(不传递num默认删除到结尾)
- 如果start < 0,则会从右至左删除指定的元素(如果负数的绝对值超过了数组长度,则全部删除)
-
num 可选,默认删除到数组的末尾,表示删除的个数 返回值是所有被删除的元素组成的数组
let arr3 = [5,6,7,8,9];
let newArr = arr3.splice(0); // start = 0,删除全部元素
console.log(arr3); // [] 会改变原数组
console.log(newArr);// [5,6,7,8,9] 返回所有被删除的元素组成的数组
let arr4 = [5,6,7,8,9];
let newArry2 = arr4.splice(1);
console.log(newArry2); //[6,7,8,9] 返回所有被删除的元素组成的数组
console.log(arr4); // [5] 改变了原数组
let arr5 = [5,6,7,8,9];
let newArray3 = arr5.splice(1,2);
console.log(newArray3);// [6,7] 删除1位置开始的2个元素并返回
console.log(arr5);// [5,8,9] 改变了原数组
let arr6 = [5,6,7,8,9];
let newArray4 = arr6.splice(-2);
console.log(newArray4); // [8,9]
console.log(arr6); // [5,6,7]
- 替换
- item1 item2...表示从删除的位置,添加第二个参数以后的内容
let arr7 = [5,6,7,8,9];
let newArray5 = arr7.splice(1,2,'b','c','e');
console.log(newArray5);// [6,7] 返回被删除元素组成的数组
console.log(arr7); //[5,b,c,e,8,9]
- 添加
- 如果不删除元素,但是又存在第三个或3个以上的参数那么就会有添加的功能
- 返回值是一个空数组
如:arr.splice(1,0, 'a', 'b', 'c'); 表示从索引为1的位置往后插入a,b,c
let arr8 = [5,6,7,8,9];
let newArray6 = arr8.splice(1,0, 'a', 'b', 'c');
console.log(newArray6); // [] 无被删除的元素
console.log(arr8); // [5,a,b,c,6,7,8,9]
!splice永远返回的是被删除的元素组成的数组
以上方法:push、pop、unshift、shift、splice均会改变原数组
6、sort()
sort(function(a,b){})
- function为可选参数,默认排序根据字符串的unicode码进行排序
- 会改变原数组
let arr = ['b', 'z', 'l', 'a'];
arr.sort();
console.log(arr); // ["a", "b", "l", "z"]
let num = [6,50,12,23];
num.sort();
console.log(num); //[12, 23, 50, 6] 默认根据unicode排序
- 还可利用sort进行数据的升序/降序、自定义、随机排序
- 升序/降序排序:return a - b 升序;renturn b - a 降序;
- 自定义排序:(见代码块)
- 随机排序:可借助Math.random方法
// 利用sort进行数组升序/降序排列
let num = [6,50,12,23];
num.sort(function(a,b) {
return a-b; // 从小到大排序
// return b-a; // 从大到小排
});
console.log(num);// [6, 12, 23, 50] 改变了原数组
//2 自定义排序
let arr2 = ['A', 'B', 'a', 'b'];
// 所有的a排在b前(不区分大小写)
arr2.sort(function(a, b) {
let a1 = a.toLowerCase();
let b1 = b.toLowerCase();
if(a1>b1) {
return 1;
}
if(a1<b1) {
return -1;
}
return 0;
});
console.log(arr2); // ["A", "a", "B", "b"]
// 3 随机排序
let arr3 = ['a', 'b' ,'c', 'd', 'e'];
arr3.sort(function(a,b) {
return Math.random() - 0.5; // -0.5~0.5
});
console.log(arr3);
7、concat()
用于拼接两个或两个以上的数组,并返回一个新数组,不会改变原数组
let arr1 = ['a'];
let arr2 = ['b'];
console.log(arr1.concat(arr2)); // ['a','b']
console.log(arr1);// ['a'] 没有改变原数组
8、join()
用于把数组拼接起来,以字符串的方式进行返回
- 不给定参数,默认以逗号分隔
- 给定参数,以该参数为分隔符进行分割
- 空数组调取join方法则返回一个空字符串
- 如果数组中只有一个元素,则直接将该元素以字符串的方式返回
- 也可以通过toString()方法以逗号分隔字符串
let arr3 = ['a', 'b', 'c'];
console.log(arr3.join()); //a,b,c
console.log(arr3.join("-"));//a-b-c
console.log(arr3.join(""));//abc
console.log(arr3); // [a,b,c] 不会改变原数组
let arr4 = [];
console.log(arr4.join("-"));// 空字符串
let arr5 = ['lalala'];
console.log(arr5.join("-")); // lalala
9、reverse()
将数组中的元素颠倒,并返回一个新的数组,会改变原数组
let arr6 = ['a', 'c', 'e'];
let arr7 = arr6.reverse();
console.log(arr7); // ["e", "c", "a"]
console.log(arr6); // ["e", "c", "a"]
10、indexOf()
indexOf(searchValue[,fromIndex])
用于查找目标数组中是否包含searchValue,如果包含则返回第一次出现的索引,不包含返回-1
- searchValue: 要查找的元素
- fromIndex 非必填,查找元素的起始位置(包含该位置)
- 如果不传递,则默认为0
- 如果formIndex < 0 且绝对值小于数组长度,根据倒数来确定查找的位置(length + formIndex)
- 如果formIndex < 0 且绝对值大于等于数组长度,则formIndex看作0
let arr8 = ['a', 'a','c','d','a'];
console.log(arr8.indexOf('a')); // 0
console.log(arr8.indexOf('a', 1)); // 1
console.log(arr8.indexOf('a', -2)); //4 即从5-2=3 (length + fromIndex)的位置开始查找
11、lastIndexOf()
lastIndexOf(searchValue[,fromIndex])
从后往前查找目标数组中指定的元素最后一个出现的位置
- searchValue: 要查找的元素
- fromIndex 非必填,查找元素的起始位置(包含该位置)
- 如果不传递,则默认为length
- 如果formIndex > 0 且大于或等于数组长度,则为length
- 如果formIndex < 0 且绝对值小于等于数组长度,根据倒数来确定查找的位置(length + formIndex)
- 如果formIndex < 0 且绝对值大于数组长度,则返回-1
let arr9 = ['a', 'a','c','d','a'];
console.log(arr9.lastIndexOf('a')); // 4
console.log(arr9.lastIndexOf('a', 6)); // 4
console.log(arr9.lastIndexOf('a', -4)); // 1
console.log(arr9.lastIndexOf('a', -5)); // 0
console.log(arr9.lastIndexOf('a', -6)); // -1
12、slice
slice(begin,end) [begin, end) 包含begin位置,不包含end位置
用于截取数组中的内容,返回一个新数组,不会影响原数组
-
begin:截取的起始位置
- 如果不给默认是0
- begin > length,返回一个空数组
- begin < 0 且绝对值小于length,则表示从倒数第几个开始截取
- begin < 0 且绝对值大于length,则表示从0开始截取(返还一整个数组)
-
end:截取的结束位置,非必须,默认截取到结尾
- end < begin,则会得到一个空数组
- end < 0 且绝对值小于length,则表示截取到倒数第几个元素
- end < 0且绝对值大于length,会得到一个空数组
- end > length,那么end会默认为数组的结尾位置
通常用arr.slice()来拷贝数组( 属于浅拷贝 )
let arr10 = ['a','b','c','d','e'];
console.log(arr10.slice()); // ['a','b','c','d','e'] 相当于拷贝数组
let arr11 = arr10.slice(2);
console.log(arr11);// ["c", "d", "e"]
console.log(arr10)// ['a','b','c','d','e'] 不会影响原数组
let arr12 = arr10.slice(-2);
console.log(arr11); // ['d','e']
let arr13 = arr10.slice(2,3);
console.log(arr13); // ["c"]
console.log(arr10.slice(2,1)); // []
console.log(arr10.slice(2, -1)); // ['c','d']
13、forEach()
forEach(callback[,thisArg])
对数组中的每一个元素,执行一次提供的函数
-
callback(ele, index, arr)
- ele:循环过程中的每一个元素
- index:当前循环的元素对应的索引
- arr:调用forEach的当前数组
-
thisArg
- 用于控制当前callback的this指向
- 可选,不传递则this默认指向window
forEach方法的返回值是undefined
let arr1 = ['1','2','a','b'];
arr1.forEach(function(ele, index, arr) {
console.log(this); // window
})
// 控制this指向当前数组:
arr1.forEach(function(item){
console.log(this); // this指向arr1(当前数组)
}, arr1);
14、filter()
用于筛选出函数中符合条件的元素,并作为一个新数组返回
let arr2 = [10,20,30,50,60,70];
let newArr = arr2.filter(function(ele, index, arr) {
return ele > 50;
}, arr2);
console.log(newArr);// [60,70]
15、map()
用于返回一个新的数组(自定义规则)
let newArray2 = arr2.map(function(ele, index, arr) {
return ele * 2;
}, arr2);
console.log(newArray2);//[20,40,60,100,120,140]
console.log(arr2);// [10,20,30,50,60,70]
16、reduce()
累计器:对数组中的每一个元素执行callback函数,将结果根据callback函数中的条件,返回单个值
语法:arr.reduce(callback[,initValue])
-
callback(result, ele, index):执行的函数
- result:上一次累计的结果
- ele:当前正在循环的元素
- index:当前正在循环的元素对应的索引值
-
initValue:对于result进行初始化(可选)
let arr = [10,20,30,40,50,6];
// 使用reduce求数组中元素的和
let sum = arr.reduce(function(result, ele, index) {
return result + ele;
}, 0);
console.log(sum);// 156
17、some()
测试数组中是否至少有一个元素通过了指定函数的测试,结果返回布尔值
语法:arr.some(callback[, thisArg])
-
callback(ele, index, array)
- ele:当前循环的元素
- index:当前循环元素的索引值
- array:当前正在操作的数组
-
thisArg:决定callback中的this指向(可选)
18、every()
测试数组中所有的元素是否能通过了指定函数的测试,结果返回布尔值
语法:arr.every(callback[, thisArg])
-
callback(ele, index, array)
- ele:当前循环的元素
- index:当前循环元素的索引值
- array:当前正在操作的数组
-
thisArg:决定callback中的this指向(可选)
类数组要转为数组后才能使用some、every方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
</head>
<body>
<ul>
<li><input type="checkbox">吃的</li>
<li><input type="checkbox">喝的</li>
<li><input type="checkbox">玩的</li>
</ul>
<input type="checkbox" id="all">全选
<button disabled>去支付</button>
</body>
<script>
let btn = document.querySelector('button');
let checkboxs = document.querySelectorAll('ul input');
let checkAll = document.querySelector('#all');
// checkboxs是类数组,要转为数组后才能使用some、every
checkboxs = [...checkboxs]
checkboxs.forEach(function(item) {
item.onclick = function() {
let result = checkboxs.some(function(ele) {
return ele.checked;
});
// 3 every
let isAllChecked = checkboxs.every(function(ele) {
return ele.checked;
});
// 是否全选
checkAll.checked = isAllChecked ? true : false;
btn.disabled = result? false : true;
}
});
// 点击全选
checkAll.onclick = function() {
if (checkAll.checked) {
checkboxs.forEach(item => item.checked = true)
btn.disabled = false
} else {
checkboxs.forEach(item => item.checked = false)
btn.disabled = true
}
}
</script>
</html>
19、Array.from
把一个类数组(有下标有length,比如NodeList)转换为真正的数组
语法:Array.from(arryLike[, mapFn[,thisArg]]) 返回值为转换之后的新数组
- 参数:
- arrayLike类数组
2.可选参数:
- mapFn 类似map方法,循环类数组时的回调函数,返回值组成新的数组
- thisArg mapFn函数执行时的this指向
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
let lis = document.querySelectorAll('#list li');
// lis.map(item=>{
// console.log(item);
// }); // 此时会报错(map is not a function),因为map只是属于数组的方法,不属于类数组
lis = Array.from(lis);
console.log(lis);
lis.map(item=>{
console.log(item); // 会依次打印出li节点
});
lis = Array.from(lis,(item,index)=>{
return index; // 将下标值组成一个新的数组
});
console.log(lis); // [0,1,2,3,4]
/*
注意,如果传递第三个参数改变回调函数的this指向的时候就不要用箭头函数了
如果使用箭头函数,this会指向window(指向声明箭头函数的作用域)
*/
let arr = [];
lis = Array.from(lis, function(item, index){
console.log(this); // [] [] [] [] []
return index;
}, arr);
</script>
</body>
</html>
总:有两种方式将类数组转换为普通数组 :
- Array.from 方法
- arr = [...arrylike] 数组展开运算
20、Array.of
Array.of(element0[, element1[, ...[, elementN]]])
将参数转成一个数组
- 参数:要放入数组中的数据
- 返回值:新数组
console.log(Array.of('1',2,3,'a'));// ['1',2,3,'a']
21、Array.isArray
Array.isArray(data)
检测数据是否是个普通数组,返回布尔值
- 参数:要检测的数据
- 返回值:true:是数组,false非数组
let lis = document.querySelectorAll('#list li');
console.log(Array.isArray(lis)); // false
lis=[...lis];
console.log(Array.isArray(lis)); // true
22、arr.find
查找数组中满足要求的第一个元素的值
语法:arr.find(callback[, thisArg])
- 参数:
-
callback
在数组每一项上执行的函数,接收3个参数:
- element:当前遍历到的元素
- index(可选):当前遍历到的索引
- array(可选):数组本身
-
thisArg(可选):执行回调时用作this的对象
- 返回值:数组中第一个满足所提供测试函数的元素的值,没有则返回undefined
let arr = [1,2,3,4];
// let val = arr.find((item, index)=> {
// if (item >= 3) {
// return true;
// }
// });
// 简写
let val = arr.find(item => item>=3);
console.log(val); // 3
23、arr.findIndex
查找数组中满足要求的第一个元素的值的索引
语法:arr.findIndex(callback[, thisArg])
- 参数:
-
callback 在数组每一项上执行的函数,接收3个参数:
- element:当前遍历到的元素
- index(可选):当前遍历到的索引
- array(可选):数组本身
-
thisArg(可选):执行回调时用作this的对象
- 返回值:数组中第一个满足所提供测试函数的元素的索引,没有则返回-1
let arr = [1,2,3,4];
let val = arr.findIndex(item => item>=3);
console.log(val); // 2
24、arr.flat
扁平化多维数组
语法:arr.flat([depth])
- 参数:
- depth(可选):指定要提取嵌套数组的结构深度,默认值为1
- 返回值:一个包含将数组与子数组中所有元素的新数组,不会改变原数组
let arr = [ ['小明','18'],
['小红', '20']
];
console.log(arr.flat()); // ['小明', '18', '小红', '20']
let arr2 = [ [1,3 , [2,[ 4 ]]]
];
// 如果嵌套太深,不知道嵌套了多少层,可以用Infinity
console.log(arr2.flat(Infinity)); // [1,3,2,4]
25、arr.flatMap
方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组
语法:arr.flatMap(callback)
- 参数:
-
callback
可以生成一个新数组的元素的函数,接收3个参数:
- currentValue:当前正在数组处理的元素
- index(可选):数组中正在处理的当前元素的索引
- array(可选):当前被处理的数组本身
-
thisArg(可选):执行回调时用作this的对象
- 返回值:一个包含将数组与子数组中所有元素的新数组
// eg1
const messages = ["Hello World", "123 456", "a b c"]
const words = messages.flatMap(item => {
return item.split(" ")
})
console.log(words)// ['Hello', 'World', '123','456','a','b','c']
// eg2
let arr = [
['小明','18'],
['小红', '20']
];
let newArray = arr.flatMap((item,index)=>{
item = item.filter((item, index)=>{
return index === 0;
});
return item;
});
console.log(newArray); // ['小明', '小红']
// eg3
let arr1 = [
[['小明', '男'],'18'],
[['小红', '女'], '20']
];
let newArray1 = arr1.flatMap((item,index)=>{
item = item.filter((item, index)=>{
return index === 0;
});
return item;
});
console.log(newArray1); // [['小明', '男'], ['小红', '女']]
!flatMap只能处理一层,如果要处理多层需要递归
26、arr.fill
用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引
语法:arr.fill(value[, start[, end]])
- 参数:
- value:用来填充数组元素的值
- start(可选):起始索引,默认值为0
- end(可选):终止索引,默认值为arr.length
- 返回值:填充后的数组(会改变原数组)
!该方法不会改变数组的长度,如果设定的终止索引超过了数组长度,只替换到数组长度的位置
let arr1 = [1,2,3,4,5];
let newArray1 = arr1.fill('a');
console.log(arr1); // ['a','a','a','a','a']
console.log(newArray1);// ['a','a','a','a','a']
let arr2 = [6,7,8,9,10];
arr2.fill('c', 1);
console.log(arr2); // [6, "c", "c", "c", "c"]
let arr3 = ['a','b','c'];
arr3.fill('7', 1, 2);
console.log(arr3); // ['a',7,'c']
let arr4 = [1,2,3];
arr4.fill('a', 1, 20);
console.log(arr4); // [1, 'a', 'a'] 不会改变数组长度
27、arr.includes
判断数组中是否包含一个指定的值
语法:arr.includes(value[, fromIndex])
1.参数:
- value:要查找的值
- fromIndex(可选):从该位置处向后查找(包含该位置)
2.返回值:布尔值,true代表数组中包含value;false代表数组中不包含value
!当数组中包含NaN时,用arr.indexOf是判断不出来的,此时用includes是可以判断出来的
const arr = ['a','b','c','d','e'];
console.log(arr.includes('c'));// true
console.log(arr.includes('c', 2));// true
const names = ["abc", "111", "222", "333", NaN]
if (names.indexOf(NaN) !== -1) {
console.log("包含NaN....1") // 不输出
}
if (names.includes(NaN)) {
console.log("包含NaN....2") // 输出
}
三、检测是否为数组
- instanceof 运算符,可以判断一个对象是否属于某种类型
- Array.isArray()用于判断一个对象是否为数组,isArray() 是 HTML5 中提供的方法
const arr = [1, 23];
const obj = {};
console.log(arr instanceof Array); // true
console.log(obj instanceof Array); // false
console.log(Array.isArray(arr)); // true
console.log(Array.isArray(obj)); // false