JS数组知识总结

304 阅读4分钟

前言

因为自己有时会记混一些JS数组操作的方法,这篇博客就对JS数组知识进行总结,常看常新。


slice 与 splice

slice:截取数组/字符串

数组/字符串.slice(start,end) [start, end) 从start下标开始,到 end-1下标结束

const arr = ['a', 'b', 'c', 'd', 'e', 'f'];
arr.slice();     // 无参数时,截取所有的元素。
arr.slice(2);    // 从第二个值开始提取,直到末尾
arr.slice(-2);   // 提取最后两个元素 负数会将其与长度相加,-2+6=4
arr.slice(2, 4); // 提取第二、三元素

将伪数组[]转化成数组

array = [].slice.call(arr);

ES6版:

array = Array.from(arr);

splice:对数组进行增删改查

数组.splice(start,length,新添加的元素1,元素2,...)

从第start位开始(初始为0),length个数据替换为新添加的,该方法返回被替换之前的length个数据,原数组也会被改变成替换之后的数据。可以理解成:删除了哪些元素,就在所在位置补充新的内容。

  • 只传前一/二个参数,删除元素
let arr = ['a', 'b', 'c', 'd', 'e', 'f'];
arr.splice(1);    //从第index为1的位置开始,删除元素
arr.splice(-2);   //删除最后两个元素,和slice同样的思想
arr.splice(1, 3); //从第index为1的位置开始,一共删除三个元素
  • length=0时,增加元素
let arr = ['a', 'b', 'c', 'e'];
let arr1=arr.splice(3,0,'d')  
console.log(arr1)    //[]
console.log(arr)     //['a', 'b', 'c', 'd', 'e'];
  • 增加+删除:变更数据
let arr = ['a', 'b', 'c', 'd'];
arr.splice(1,2,1,2,3,4,5) 
console.log(arr1)     //['b','c']
console.log(arr)      //['a', 1, 2, 3, 4, 5, 'd']
  • 综合例子
let arr = [];
arr[0]=1;
arr[1]=2;
arr[3]='abc';
arr[5]=true;
console.log(arr);  // [1, 2, empty, "abc", empty, true]
let arr1=arr.slice(0,4)
console.log(arr1); //[1, 2, empty, "abc"]   
console.log(arr);  //[1, 2, empty, "abc", empty, true]  没有改变原数组
let arr2=arr.splice(0,3,3,4,5)  //从下标为0开始,将这3个替换为3,4,5
console.log(arr2); //[1, 2, empty]  选中的这三个
console.log(arr)   //[3, 4, 5, "abc", empty, true]  替换完的数组

区别

  • 功能:slice是截取数组/字符串的,splice是对数组进行增删改查的
  • 二者都会返回新的数组,但slice方法不会改变原数组,splice方法改变原数组

数组与字符串的转换——split 与 join

split:将 字符串 拆分成 数组

新的数组 = str.split(分隔符); 返回一个数组,不改变原字符串。

let str="a b c"
let arr1=str.split(" ")  //["a","b","c"]

join:将 数组 转换为 字符串

新的字符串 = 原数组.join(参数); 默认使用,作为连接符,返回一个字符串,不会改变原数组

let arr = ['a', 'b', 'c'];
let str1=arr.join();      //"a,b,c"   此时和toString()的效果是一致的
let str2=arr.join('-');   //"a-b-c"

map 与 foreach

mapforEach 是数组中的帮助器方法,可以轻松地在数组上循环。我们曾经像下面这样循环遍历一个数组,没有任何辅助函数。

遍历:for + let

如果要循环遍历一个数组,我们很容易想到使用 for+let

let arr = [1,2,3];
for (let i = 0; i < arr.length; i += 1) {
  console.log(arr[i]);
}

map

map 的作用与 for 循环完全相同,只是 map 会创建一个新数组,其结果是在调用数组中的每个元素上调用提供的函数。

数组.map(fn) 回调函数fn接受3个参数:数组的当前值str;当前值在数组中的位置i;原始数组origin

let arr = [1,2,3];
let fn = (str, i, origin) => {
  console.log(`${i}: ${str} / ${origin}`);
};
arr.map(fn);
// 0: 1 / 1,2,3
// 1: 2 / 1,2,3
// 2: 3 / 1,2,3

也可以在回调里只传一个参数:

arr.map((str) => { console.log(str); })
//1
//2
//3

以下遍历后,map 后新生成的数组不等于原始数组:

let arr1=arr.map(i =>i)
arr1  //[1,2,3]
arr   //[1,2,3]

forEach

数组.forEach(fn),下例中的forEach与map用法相同,都是接受一个回调函数fn作为参数:

let arr = [1,2,3];
let fn = (str, i, origin) => {
  console.log(`${i}: ${str} / ${origin}`);
};
arr.forEach(fn);
// 0: 1 / 1,2,3
// 1: 2 / 1,2,3
// 2: 3 / 1,2,3

区别

主要就在于是否有返回值map 返回基于原始数组的一个新数组,但是 forEach 的返回值是undefined。它们都能确保了原来数组的不变。

[1,2,3].map(d => d + 1); // [2, 3, 4];
[1,2,3].forEach(d => d + 1); // undefined;

综上所述,建议在创建一个新的数组时使用map;当你不需要制作一个新的数组,而是要对数据做一些事情时,就使用forEach。

数组 与 类数组

类数组

let list = {
    0 : 1,
    1 : 2,
    2 : 3,
    length : 3
}
//list.push()  报错

区别

  • 类数组不具备数组的方法(如splice,split,push...)
  • 类数组是一个普通对象,数组类型是Array

类数组 转化成 数组

类数组不能使用数组的方法,因此我们需要将类数组转化成真正的数组

  • ES6中的 Array.from() let arr = Array.from(list);
  • ES6+ 扩展运算符 let arr = [...HTMLcontrion]
  • 使用apply let arr = [].concat.apply([],list)

注意

1 字符串赋值问题

有一个字符串s="abcabcbb",虽然可以遍历取到s[i],但是不能对其直接赋值,必须将字符串.split('')转换成数组,数组里的每一项都是字符,再将数组join拼接成字符串。

2 数组排序sort()问题

原理:当数组长度小于等于10的时候,采用插入排序,大于10的时候,采用快速排序

  1. 无参数情况:默认会以字典排序的顺序为结果,如果处理字符串类型的数组直接使用sort就可以,数值型可能会返回错误。
let arr = [10, 5, 40, 25, 100, 1];
arr.sort();
//[1, 10 ,100, 25, 40, 5]
  1. 传入比较函数的情况: 具体的返回结果与比较函数有关。

对函数进行传参,可以让数组内的值按照升序/降序排序:

let arr= [40,100,1,5,25,10];
arr.sort((a,b)=>{return a-b});  //数字升序
//1,5,10,25,40,100

let fruits = ["Banana""Orange""Apple""Mango"];
fruits.sort();                //字母降序
fruits.reverse();
//Orange,Mango,Banana,Apple

还在不断更新中