Array API
- 类数组对象,可迭代对象,数组之间的区别?
类数组对象
类数组有几个必要组成部分:
- 属性要为索引(数字)属性;
- 必须有length属性
- 最好加上数组的push和splice方法
可迭代对象
红宝书184
可迭代对象是一种抽象的说法。基本上,可以把可迭代对象理解成数组或集合这样的集合类型的对 象。它们包含的元素都是有限的,而且都具有无歧义的遍历顺序
数组
红宝书p138
ECMAScript 数组也是一组有序的数据,但跟其他语言不同的是,数组中每个槽位可以存储任意类型的数据。这意味着可以创建一个数组,它的第一个元素 是字符串,第二个元素是数值,第三个是对象。ECMAScript 数组也是动态大小的,会随着数据添加而自动增长。
将类数组转换成数组
- Array.prototype.slice.call()
- Array.from()
- ES6展开运算符
- Array.prototype.concat.apply()
- 罗列数组的常见方法
静态方法
- Array.isArray() Array.isArray() 用于确定传递的值是否是一个 Array。
Array.isArray([1, 2, 3]); // true Array.isArray({foo: 123}); // false Array.isArray('foobar'); // false Array.isArray(undefined); // false 复制代码
- concat()方法 用于连接两个或多个数组
const arr = [1,2,3] console.log(arr.concat(4,5,6)); // [ 1, 2, 3, 4, 5, 6 ] console.log(arr); // [ 1, 2, 3 ] 复制代码
- join()方法 用于把数组中的所有元素放入一个字符串,改变数组,返回一个字符串,该字符串是通过把数组元素转化为字符串,然后把这些字符串连接起来
const arr = [1,2,3] console.log(arr.join()); // 1,2,3 console.log(arr.join('|')); //1|2|3 复制代码
- pop()用于删除并返回数组的最后一个元素,改变数组
const arr = [1,2,3] console.log(arr.pop()); // 3 console.log(arr); // [ 1, 2 ] 复制代码
⑤shift()删除并返回数组的第一个元素,改变数组
const arr = [1,2,3] console.log(arr.shift()) // 1 console.log(arr) // [ 2, 3 ] 复制代码
- unshift()想数组投添加元素,并返回新的数组,改变数组,IE不兼容
const arr = [1,2,3] console.log(arr.unshift(4)) // 4 console.log(arr) // [4, 1, 2, 3 ] 复制代码
- slice()从已有的数组中返回选中的元素,不包括第二个位置的元素
第一个参数必须,规定从何处开始选取,如果是负数,那么他规定从数组尾部开始算起的位置,也就是说-1指最后一个元素,-2指倒数第二个元素
第二个参数可选,规定从何处结束选取,改参数是数组片段结束处的数组下标。如果没有指定该参数,那么切分的数组包含从start到数组结束的所有元素。
const arr = [1,2,3] console.log(arr.slice(0,1)) // [ 1 ] console.log(arr) // [1, 2, 3 ] console.log(arr.slice(-3,-2)) // [ 1 ] 复制代码
- splice()方法向/从数组中添加/删除项目,然后返回被删除的项目,改变数组
第一个参数必须,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置 第二个参数必须,表示要删除的项目数量,如果设置为0,则不会删除项目 第三个参数可选,向数组添加的新项目
const arr = [1,2,3] console.log(arr.splice(1,2,4,5,6)) // [ 2, 3 ] console.log(arr) // [ 1, 4, 5, 6 ] 复制代码
- toString()将数组转化为字符串,与join相似,但join可以加参数,不改变原数组
const arr = [1,2,3] console.log(arr.toString()) //1,2,3 console.log(arr) // [ 1, 4, 5, 6 ] 复制代码
- Array.prototype.every() every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
const isBelowThreshold = (currentValue) => currentValue < 40; const array1 = [1, 30, 39, 29, 10, 13]; console.log(array1.every(isBelowThreshold)); // expected output: true 复制代码
- Array.prototype.some()
some() 方法测试数组中是不是至少有 1 个元素通过了被提供的函数测试。它返回的是一个 Boolean 类型的值。
const array = [1, 2, 3, 4, 5]; // checks whether an element is even const even = (element) => element % 2 === 0; console.log(array.some(even)); // expected output: true 复制代码
- Array.prototype.filter()
filter() 方法创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present']; const result = words.filter(word => word.length > 6); console.log(result); // expected output: Array ["exuberant", "destruction", "present"] 复制代码
- Array.prototype.forEach()
forEach() 方法对数组的每个元素执行一次给定的函数。
const array1 = ['a', 'b', 'c']; array1.forEach(element => console.log(element)); // expected output: "a" // expected output: "b" // expected output: "c" 复制代码
搜索和位置方法
- Array.prototype.findIndex() findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1
const array1 = [5, 12, 8, 130, 44]; const isLargeNumber = (element) => element > 13; console.log(array1.findIndex(isLargeNumber)); // expected output: 3 复制代码
- Array.prototype.find()
find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
const array1 = [5, 12, 8, 130, 44]; const found = array1.find(element => element > 10); console.log(found); // expected output: 12 复制代码
- Array.prototype.indexOf()
indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
const beasts = ['ant', 'bison', 'camel', 'duck', 'bison']; console.log(beasts.indexOf('bison')); // expected output: 1 复制代码
- Array.prototype.lastIndexOf()
lastIndexOf() 方法返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始。
const animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo']; console.log(animals.lastIndexOf('Dodo')); // expected output: 3 复制代码
- Array.prototype.includes() includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。
const array1 = [1, 2, 3]; console.log(array1.includes(2)); // expected output: true 复制代码
- 操作方法
- Array.prototype.flat()
flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
const arr1 = [0, 1, 2, [3, 4]]; console.log(arr1.flat()); // expected output: [0, 1, 2, 3, 4] const arr2 = [0, 1, 2, [[[3, 4]]]]; console.log(arr2.flat()); // expected output: [0, 1, 2, [3, 4]] console.log(arr2.join("")); 复制代码
- Array.prototype.fill()
fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
const array1 = [1, 2, 3, 4]; // fill with 0 from position 2 until position 4 console.log(array1.fill(0, 2, 4)); // expected output: [1, 2, 0, 0] 复制代码
- Array.prototype.copyWithin()
copyWithin() 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它
const array1 = ['a', 'b', 'c', 'd', 'e']; // copy to index 0 the element at index 3 console.log(array1.copyWithin(0, 3, 4)); // expected output: Array ["d", "b", "c", "d", "e"] // copy to index 1 all elements from index 3 to the end console.log(array1.copyWithin(1, 3)); // expected output: Array ["d", "d", "e", "d", "e"] 复制代码
- Array.prototype.map()
map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。
const array1 = [1, 4, 9, 16]; // pass a function to map const map1 = array1.map(x => x * 2); console.log(map1); // expected output: Array [2, 8, 18, 32] 复制代码
- Array.prototype.flatMap()
flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为 1 的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些。
var arr1 = [1, 2, 3, 4]; arr1.map(x => [x * 2]); // [[2], [4], [6], [8]] arr1.flatMap(x => [x * 2]); // [2, 4, 6, 8] 复制代码
- 迭代方法
Array.prototype.entries()
entries() 方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。
Array.prototype.keys()
keys() 方法返回一个包含数组中每个索引键的Array Iterator对象。
Array.prototype.values()
values() 方法返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值。
- 迭代器方法
- Array.prototype.reduce() 附带reduceRight() reduceLeft()
reduce() 方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。
第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被作为初始值 initialValue,迭代器将从第二个元素开始执行(索引为 1 而不是 0)。
- 顺序相关方法
- sort()将数组进行排序,改变数组,如果没有参数,将按字母顺序对数组中的元素进行排序
const arr = [1,2,3] console.log(arr.sort((a,b)=> b - a)) // [ 3, 2, 1 ] console.log(arr) // [ 3, 2, 1 ] 复制代码
- reverse()将数组倒序,改变数组
const arr = [1,2,3] console.log(arr.reverse()); // [ 3, 2, 1 ] console.log(arr); // [ 3, 2, 1 ] 复制代码
- 实现 deepFlat 方法。
const { log } = console; const arr = [1, [2], [3, [4]], [[[6]]]]; log(arr.flat()); // -> [ 1, 2, 3, [ 4 ], [ [ 6 ] ] ] Array.prototype.deepFlat = function deepFlat() { let arr = this function deep(arr) { arr = arr.flat() for (let i = 0; i < arr.length; i++) { if(Array.isArray(arr[i])) { arr = arr.flat() i = 0; } } return arr } return deep(arr) }; log(arr.deepFlat()); // -> [ 1, 2, 3, 4, 6 ] // 利用参数 Array.prototype.deepFlat2 = function deepFlat() { return this.flat(this.join().replace(/,/g,'').length); }; console.log([ 1, 2, 3, [ 4 ], [ [ 6 ] ] ].deepFlat2()); // 扩展运算符(参考别的) Array.prototype.deepFlat1 = function deepFlat() { let arrB = [].concat(...this); while(arrB.some( item => Array.isArray(item) )){ arrB = [].concat(...arrB); } return arrB }; console.log([ 1, 2, 3, [ 4 ], [ [ 6 ] ] ].deepFlat1()); 复制代码
- 实现 reduce 方法
const { log } = console; Array.prototype.reduce = function reduce(reducer, initialValue) { for(let i = 0; i < this.length; i++) { initialValue = reducer(initialValue,this[i]) } return initialValue }; log([1, 2, 3].reduce((pre, cur) => pre + cur, 10)); 复制代码
- 实现 shuffle 方法
红宝书p262
const { log } = console; Array.prototype.shuffle = function shuffle() { // 洗牌算法 for (let i = this.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [this[i], this[j]] = [this[j], this[i]]; } }; const nums = [1, 2, 3, 4, 5]; log(nums.shuffle()); // -> [ 4, 1, 5, 2, 3 ]