本文是 重温基础 系列文章的第十篇。 今日感受:平安夜,多棒。系列目录:【复习资料】ES6/ES7/ES8/ES9资料整理(个人整理)【重温基础】1.语法和数据类型【重温基础】2.流程控制和错误处理【重温基础】3.循环和迭代【重温基础】4.函数【重温基础】5.表达式和运算符【重温基础】6.数字【重温基础】7.时间对象【重温基础】8.字符串【重温基础】9.正则表达式本章节复习的是JS中的数组,以索引进行排序。 前置知识: 数组是一个有序的数据集合,使用数组名称和索引进行访问。let arr = [1,2,3];arr[0] = 1;在JavaScript中数组没有明确数据类型。let arr = [1, ‘hi’, undefined, fun()];1.创建数组创建数组方法有3种:let arr = new Array(ele1, ele2, ele3, …, eleN);let arr = Array(ele1, ele2, ele3, …, eleN);let arr = [ele1, ele2, ele3, …, eleN];上面是已知数组元素,另外一种还有创建一个长度不为0,且有没有任何元素的数组:let len = 5;let arr = new Array(len); // 方法1let arr = Array(len); // 方法2let arr = []; // 方法3arr.length = len;若传入的数组长度不是整数,则报错:let arr = new Array(3.5); let arr = Array(3.5); let arr = [];arr.length = 3.5;//Uncaught RangeError: Invalid array length其中要注意这两种创建方法是不同的:let arr1 = new Array(4); // [empty × 4]let arr2 = [4]; // [4]for(let k in arr1){ console.log(k);} // undefinedfor(let k in arr2){ console.log(k);} // 02.使用数组2.1 简单使用获取数组指定位置的值:let a = [1,2,5];a[0]; // 1a[2]; // 5a[3]; // undefined获取数组长度:let a = [1,2,5];a.length; // 3a[“length”]; // 3设置数组指定位置的值:let a = [1,2,5];a[0] = 9;a[2] = 99;a[3] = 999;2.2 理解数组length数组的索引值是从0开始,即上面数组索引0的是1,索引1的值是2,依次下去。数组length永远返回的是数组最后一个元素的索引加1。可通过arr.length = 0来清空数组。可通过arr.length = len来设置数组长度。2.3 遍历数组遍历数组就是以某种方法处理数组的每个元素,简单如下:使用for循环:let arr = [“pingan”, “leo”, “robin”];for (let i = 0; i<arr.length; i++){ // 处理元素的操作 console.log(第${i}个元素是:${arr[i]};)}// 第0个元素是:pingan;// 第1个元素是:leo;// 第2个元素是:robin;使用for…in:let arr = [“pingan”, “leo”, “robin”];for(let i in arr){ console.log(第${i}个元素是:${arr[i]};)}// 第0个元素是:pingan;// 第1个元素是:leo;// 第2个元素是:robin;使用forEach:arr.forEach(callback) 接收一个回调方法。 callback(val, index, array) : 接收三个参数:* val : 当前处理的元素; * index : 当前处理的元素的索引; * array : 正在处理的数组; 可参考MDN Array.prototype.forEach 的详细介绍。let arr = [“pingan”, “leo”, “robin”];arr.forEach(function(val, i, array){ console.log(第${i}个元素是:${val};)})3. 数组方法(访问和修改)方法名称方法介绍concat()连接两个或更多的数组,并返回结果。join()把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。pop()删除并返回数组的最后一个元素push()向数组的末尾添加一个或更多元素,并返回新的长度。reverse()颠倒数组中元素的顺序。shift()删除并返回数组的第一个元素slice()从某个已有的数组返回选定的元素sort()对数组的元素进行排序splice()删除元素,并向数组添加新元素。toSource()返回该对象的源代码。toString()把数组转换为字符串,并返回结果。toLocaleString()把数组转换为本地数组,并返回结果。unshift()向数组的开头添加一个或更多元素,并返回新的长度。valueOf()返回数组对象的原始值indexOf()在数组中搜索指定元素并返回第一个匹配的索引lastIndexOf()在数组中搜索指定元素并返回最后一个匹配的索引可参考W3school JavaScript Array 对象 的详细介绍。3.1 concat()连接两个或更多的数组,并返回一个新数组。语法:arr.concat(a1, a2, …, an);参数:arr:目标数组; a1,a2,…,an:需要合并的元素;let a1 = [1,2,3];let a2 = [9,99,999];let a = a1.concat(a2);// [1, 2, 3, 9, 99, 999]3.2 join()使用指定分隔符,连接两个或多个数组的元素,返回一个字符串。语法:arr.join(sep);参数:arr:目标数组; sep:连接的分隔符,默认值为“,”;let arr = [“pingan”, “leo”, “robin”];arr.join(); // “pingan,leo,robin"arr.join(”"); // “pinganleorobin"arr.join(”,"); // “pingan,leo,robin"3.3 pop()和push()pop(): 删除并返回数组最后一个元素,改变原数组。push(item): 向数组末尾添加一个或多个元素,改变原数组,返回新的数组长度。方便记忆和理解:两个都是从数组末尾操作,pop()是删除最后一个元素,push()是向最后一位添加新的元素。let arr = [“pingan”, “leo”];let a1 = arr.pop(); // “leo"let a2 = arr.push(“robin”,“hi”); // 3arr; // [“pingan”, “robin”, “hi”]3.4 shift()和unshift()shift(): 删除并返回数组第一个元素,改变原数组。unshift(item): 向数组头部添加一个或多个元素,改变原数组,返回新的数组长度。方便记忆和理解:两个都是从数组头部操作,shift()是删除第一个元素,unshift()是向第一位添加新的元素。let arr = [“pingan”, “leo”];let a1 = arr.shift(); // “pingan"let a2 = arr.unshift(“robin”,“hi”); // 3arr; // [“robin”, “hi”, “leo”]3.5 reverse()颠倒数组中元素的顺序,改变原数组。let arr = [1, 2, 3, 4];arr.reverse(); // [4, 3, 2, 1]3.6 slice()用于提取数组中一个片段,作为新数组返回。 slice(start[,end]): 接收2个参数:start: 必需,指定起始索引,若负数则从数组最后开始算起,-1为倒数第一位,-2为倒数第二位,以此类推。end: 可选,指定结束索引,若没传则表示到数组结束。注意: end若有指定的话,是不包含end索引上的值。let arr = [1, 2, 3, 5, 6];let a1 = arr.slice(2); // [3, 5, 6]let a2 = arr.slice(2,3); // [3]3.7 splice()从数组中删除指定索引开始的项目,然后返回被删除的项目。语法:arr.splice(index, num, a1, a2,…,an);参数:index: 必需,起始位置的索引,若负数则从数组最后开始算起; num:必需,删除的数量,若为0则不删除; a1,a2,…an:可选,为数组添加的元素;let arr = [1, 2, 3, 4];let a = arr.splice(1, 2, “hi”, “leo”);// a =>  [2, 3]// arr => [1, “hi”, “leo”, 4]3.8 sort()对数组的元素进行排序,改变原数组。 可接受一个回调方法作为比较函数,来决定排序方式。 比较函数应该具有两个参数 a 和 b,返回值如下: 若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。若 a 等于 b,则返回 0。若 a 大于 b,则返回一个大于 0 的值。let a1 = [1,3,6,9,10];a1.sort(); // [1, 10, 3, 6, 9]a1.sort(function(a,b){ return a > b ? 1 : a < b ? -1 : 0;}) // [1, 3, 6, 9, 10]3.9 indexOf()和lastIndexOf()两者都是在数组搜索指定元素,只是indexOf()返回的是搜索到的第一个元素的索引,而lastIndexOf()返回的是搜索到的最后一个元素的索引。 语法: indexOf(ele[,start])和lastIndexOf(ele[,start]); 参数:ele: 需要搜索的元素。start: 开始搜索的索引。let arr = [“hh1”, “hh2”, “hh2”, “hh2”, “hh3”, “hh4”];let a1 = arr.indexOf(“hh2”); // 1let a2 = arr.lastIndexOf(“hh2”); // 3let a3 = arr.indexOf(“hh2”,2); // 24. 数组方法(迭代)方法名称方法介绍forEach()为数组中的每个元素执行一次回调函数。every()如果数组中的每个元素都满足测试函数,则返回 true,否则返回 false。some()如果数组中至少有一个元素满足测试函数,则返回 true,否则返回 false。filter()将所有在过滤函数中返回 true 的数组元素放进一个新数组中并返回。map()返回一个由回调函数的返回值组成的新数组。reduce()从左到右为每个数组元素执行一次回调函数,并把上次回调函数的返回值放在一个暂存器中传给下次回调函数,并返回最后一次回调函数的返回值。reduceRight()从右到左为每个数组元素执行一次回调函数,并把上次回调函数的返回值放在一个暂存器中传给下次回调函数,并返回最后一次回调函数的返回值。以下是ES6规范新增的数组方法:方法名称方法介绍keys() 返回一个数组迭代器对象,该迭代器会包含所有数组元素的键。values() 返回一个数组迭代器对象,该迭代器会包含所有数组元素的值。entries() 返回一个数组迭代器对象,该迭代器会包含所有数组元素的键值对。find() 找到第一个满足测试函数的元素并返回那个元素的值,如果找不到,则返回 undefined。findIndex() 找到第一个满足测试函数的元素并返回那个元素的索引,如果找不到,则返回 -1。可参考MDN Array 的详细介绍。4.1 forEach()对数组的每个元素执行一次提供的函数。 语法: arr.forEach(callback)。 参数: callback(val, index, arr) : 需要执行的函数,接收三个参数:val : 正在处理的当前元素;index : 可选,正在处理的当前元素的索引;arr : 可选,正在操作的数组;let a = [1,3,5,7];a.forEach(function(val, index, arr){ arr[index] = val * 2})a ; // [2, 6, 10, 14]4.2 every()测试数组的所有元素是否都通过了指定函数的测试。 语法: arr.every(callback)。 参数: callback(val, index, arr) : 需要执行的函数,接收三个参数:val : 正在处理的当前元素;index : 可选,正在处理的当前元素的索引;arr : 可选,正在操作的数组;返回值: 若都通过返回true,否则返回false。let a = [1, “”, “aa”, 13, 6];let res = a.every(function(val, index, arr){ return typeof val == “number”;})res;// falselet b = [1, 2, 3];let r = b.every(function(val, index, arr){ return typeof val == “number”;})r; // true4.3 some()测试数组中的某些元素是否通过由提供的函数实现的测试。 语法: arr.some(callback)。 参数: callback(val, index, arr) : 需要执行的函数,接收三个参数:val : 正在处理的当前元素;index : 可选,正在处理的当前元素的索引;arr : 可选,正在操作的数组;返回值: 若有一个通过返回true,否则返回false。let a = [1, “”, “aa”, 13, 6];let res = a.some(function(val, index, arr){ return typeof val == “number”;})res;// truelet b = [1, 2, 3];let r = b.some(function(val, index, arr){ return typeof val == “number”;})r; // true4.4 filter()将所有在过滤函数中返回 true 的数组元素放进一个新数组中并返回。 语法: arr.filter(callback)。 参数: callback(val, index, arr) : 需要执行的函数,接收三个参数:val : 正在处理的当前元素;index : 可选,正在处理的当前元素的索引;arr : 可选,正在操作的数组;返回值: 一个返回通过测试的元素的数组,若都没有则返回空数组。let a = [1, “”, “aa”, 13, 6];let res = a.filter(function(val, index, arr){ return typeof val == “number”;})res;//[1, 13, 6]4.5 map()传入一个操作函数,对每个元素执行此方法,并返回一个执行后的数组。 语法: arr.map(callback)。 参数: callback(val, index, arr) : 需要执行的函数,接收三个参数:val : 正在处理的当前元素;index : 可选,正在处理的当前元素的索引;arr : 可选,正在操作的数组;返回值: 一个新数组,每个元素都是回调函数的结果。let a = [1, 3, 5];let b = a.map(function(val, index, arr){ return val + 2;})b; //[3, 5, 7]5. 数组的拓展(ES6)5.1 拓展运算符拓展运算符使用(…),类似rest参数的逆运算,将数组转为用(,)分隔的参数序列。console.log(…[1, 2, 3]); // 1 2 3 console.log(1, …[2,3], 4); // 1 2 3 4拓展运算符主要使用在函数调用。function f (a, b){ console.log(a, b);}f(…[1, 2]); // 1 2function g (a, b, c, d, e){ console.log(a, b, c, d, e);}g(0, …[1, 2], 3, …[4]); // 0 1 2 3 4若拓展运算符后面是个空数组,则不产生效果。[…[], 1]; // [1]替代apply方法// ES6之前function f(a, b, c){…};var a = [1, 2, 3];f.apply(null, a);// ES6之后function f(a, b, c){…};let a = [1, 2, 3];f(…a);// ES6之前Math.max.apply(null, [3,2,6]);// ES6之后Math.max(…[3,2,6]);拓展运算符的运用(1)复制数组:通常我们直接复制数组时,只是浅拷贝,如果要实现深拷贝,可以使用拓展运算符。// 通常情况 浅拷贝let a1 = [1, 2];let a2 = a1; a2[0] = 3;console.log(a1,a2); // [3,2] [3,2]// 拓展运算符 深拷贝let a1 = [1, 2];let a2 = […a1];// let […a2] = a1; // 作用相同a2[0] = 3;console.log(a1,a2); // [1,2] 3,2合并数组:注意,这里合并数组,只是浅拷贝。let a1 = [1,2];let a2 = [3];let a3 = [4,5];// ES5 let a4 = a1.concat(a2, a3);// ES6let a5 = […a1, …a2, …a3];a4[0] === a1[0]; // truea5[0] === a1[0]; // true(3)与解构赋值结合:与解构赋值结合生成数组,但是使用拓展运算符需要放到参数最后一个,否则报错。let [a, …b] = [1, 2, 3, 4]; // a => 1 b => [2,3,4]let [a, …b] = [];// a => undefined b => []let [a, …b] = [“abc”];// a => “abc” b => []5.2 Array.from()将 类数组对象 和 可遍历的对象,转换成真正的数组。// 类数组对象let a = { ‘0’:‘a’, ‘1’:‘b’, length:2}let arr = Array.from(a);// 可遍历的对象let a = Array.from([1,2,3]);let b = Array.from({length: 3});let c = Array.from([1,2,3]).map(x => x * x);let d = Array.from([1,2,3].map(x => x * x));5.3 Array.of()将一组数值,转换成数组,弥补Array方法参数不同导致的差异。Array.of(1,2,3); // [1,2,3]Array.of(1).length; // 1Array(); // []Array(2); // [,] 1个参数时,为指定数组长度Array(1,2,3); // [1,2,3] 多于2个参数,组成新数组5.4 find()和findIndex()find()方法用于找出第一个符合条件的数组成员,参数为一个回调函数,所有成员依次执行该回调函数,返回第一个返回值为true的成员,如果没有一个符合则返回undefined。[1,2,3,4,5].find( a => a < 3 ); // 1回调函数接收三个参数,当前值、当前位置和原数组。[1,2,3,4,5].find((value, index, arr) => { // …});findIndex()方法与find()类似,返回第一个符合条件的数组成员的位置,如果都不符合则返回-1。[1,2,3,4].findIndex((v,i,a)=>{ return v>2;}); // 25.5 fill()用于用指定值填充一个数组,通常用来初始化空数组,并抹去数组中已有的元素。new Array(3).fill(‘a’); // [‘a’,‘a’,‘a’][1,2,3].fill(‘a’); // [‘a’,‘a’,‘a’]并且fill()的第二个和第三个参数指定填充的起始位置和结束位置。[1,2,3].fill(‘a’,1,2);// [1, “a”, 3]5.6 entries(),keys(),values()主要用于遍历数组,entries()对键值对遍历,keys()对键名遍历,values()对键值遍历。for (let i of [‘a’, ‘b’].keys()){ console.log(i)}// 0// 1for (let e of [‘a’, ‘b’].values()){ console.log(e)}// ‘a’// ‘b’for (let e of [‘a’, ‘b’].entries()){ console.log(e)}// 0 ‘a’// 1 ‘b'5.7 includes()用于表示数组是否包含给定的值,与字符串的includes方法类似。[1,2,3].includes(2); // true[1,2,3].includes(4); // false[1,2,NaN].includes(NaN); // true第二个参数为起始位置,默认为0,如果负数,则表示倒数的位置,如果大于数组长度,则重置为0开始。[1,2,3].includes(3,3); // false[1,2,3].includes(3,4); // false[1,2,3].includes(3,-1); // true[1,2,3].includes(3,-4); // true5.8 flat(),flatMap()flat()用于将数组一维化,返回一个新数组,不影响原数组。 默认一次只一维化一层数组,若需多层,则传入一个整数参数指定层数。 若要一维化所有层的数组,则传入Infinity作为参数。[1, 2, [2,3]].flat(); // [1,2,2,3][1,2,[3,[4,[5,6]]]].flat(3); // [1,2,3,4,5,6][1,2,[3,[4,[5,6]]]].flat(‘Infinity’); // [1,2,3,4,5,6]flatMap()是将原数组每个对象先执行一个函数,在对返回值组成的数组执行flat()方法,返回一个新数组,不改变原数组。 flatMap()只能展开一层。[2, 3, 4].flatMap((x) => [x, x * 2]); // [2, 4, 3, 6, 4, 8] 6. 数组的拓展(ES7)6.1 Array.prototype.includes()方法includes()用于查找一个值是否在数组中,如果在返回true,否则返回false。[‘a’, ‘b’, ‘c’].includes(‘a’); // true[‘a’, ‘b’, ‘c’].includes(’d’); // falseincludes()方法接收两个参数,搜索的内容和开始搜索的索引,默认值为0,若搜索值在数组中则返回true否则返回false。[‘a’, ‘b’, ‘c’, ’d’].includes(‘b’); // true[‘a’, ‘b’, ‘c’, ’d’].includes(‘b’, 1); // true[‘a’, ‘b’, ‘c’, ’d’].includes(‘b’, 2); // false与indexOf方法对比,下面方法效果相同:[‘a’, ‘b’, ‘c’, ’d’].indexOf(‘b’) > -1; // true[‘a’, ‘b’, ‘c’, ’d’].includes(‘b’); // true includes()与indexOf对比:includes相比indexOf更具语义化,includes返回的是是否存在的具体结果,值为布尔值,而indexOf返回的是搜索值的下标。includes相比indexOf更准确,includes认为两个NaN相等,而indexOf不会。let a = [1, NaN, 3];a.indexOf(NaN); // -1a.includes(NaN); // true另外在判断+0与-0时,includes和indexOf的返回相同。[1, +0, 3, 4].includes(-0); // true[1, +0, 3, 4].indexOf(-0); // 1参考资料1.MDN 索引集合类 2.MDN 数组对象 3.W3school JavaScript Array 对象本部分内容到这结束Author王平安E-mailpingan8787@qq.com博 客www.pingan8787.com微 信pingan8787每日文章推荐https://github.com/pingan8787…ES小册es.pingan8787.com