JavaScript初级篇章——数组常用方法

258 阅读8分钟

一、数组创建方式

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...])

  1. 删除
  • 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]
  1. 替换
  • 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]
  1. 添加
  • 如果不删除元素,但是又存在第三个或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()

用于把数组拼接起来,以字符串的方式进行返回

  1. 不给定参数,默认以逗号分隔
  2. 给定参数,以该参数为分隔符进行分割
  3. 空数组调取join方法则返回一个空字符串
  4. 如果数组中只有一个元素,则直接将该元素以字符串的方式返回
  5. 也可以通过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]]) 返回值为转换之后的新数组

  1. 参数:
  • 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>

总:有两种方式将类数组转换为普通数组

  1. Array.from 方法
  2. arr = [...arrylike] 数组展开运算
20、Array.of

Array.of(element0[, element1[, ...[, elementN]]])

将参数转成一个数组

  1. 参数:要放入数组中的数据
  2. 返回值:新数组
console.log(Array.of('1',2,3,'a'));// ['1',2,3,'a']
21、Array.isArray

Array.isArray(data)

检测数据是否是个普通数组,返回布尔值

  1. 参数:要检测的数据
  2. 返回值: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])

  1. 参数:
  • callback

    在数组每一项上执行的函数,接收3个参数:

    • element:当前遍历到的元素
    • index(可选):当前遍历到的索引
    • array(可选):数组本身
  • thisArg(可选):执行回调时用作this的对象

  1. 返回值:数组中第一个满足所提供测试函数的元素的值,没有则返回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])

  1. 参数:
  • callback 在数组每一项上执行的函数,接收3个参数:

    • element:当前遍历到的元素
    • index(可选):当前遍历到的索引
    • array(可选):数组本身
  • thisArg(可选):执行回调时用作this的对象

  1. 返回值:数组中第一个满足所提供测试函数的元素的索引,没有则返回-1
let arr = [1,2,3,4];
let val = arr.findIndex(item => item>=3);
console.log(val); // 2
24、arr.flat

扁平化多维数组

语法:arr.flat([depth])

  1. 参数:
  • depth(可选):指定要提取嵌套数组的结构深度,默认值为1
  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)

  1. 参数:
  • callback

    可以生成一个新数组的元素的函数,接收3个参数:

    • currentValue:当前正在数组处理的元素
    • index(可选):数组中正在处理的当前元素的索引
    • array(可选):当前被处理的数组本身
  • thisArg(可选):执行回调时用作this的对象

  1. 返回值:一个包含将数组与子数组中所有元素的新数组
// 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]])

  1. 参数:
  • value:用来填充数组元素的值
  • start(可选):起始索引,默认值为0
  • end(可选):终止索引,默认值为arr.length
  1. 返回值:填充后的数组(会改变原数组)

该方法不会改变数组的长度,如果设定的终止索引超过了数组长度,只替换到数组长度的位置

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