最近看了手写数组API之后,发现数组中还有很多方法一知半解,而且数组在开发中特别常用,那么我们应该对数组的各种属性方法了然于心,才能做到游刃有余,所以今天特地出了这一期文章。
目录
3.2Array.of(element0[, element1[, ...[, elementN]]])
3.3Array.from(arrayLike[, mapFn[, thisArg]])
4.1.1arr.indexOf(searchElement[, fromIndex])
4.1.2arr.lastIndexOf(searchElement[, fromIndex])
4.1.3arr.includes(valueToFind[, fromIndex])
4.2.1arr.find(callback[, thisArg])
4.2.2arr.findIndex(callback[, thisArg])
4.3.1arr.some(callback[, thisArg])
4.4.1arr.every(callback[, thisArg])
4.5.1arr.push(element1, ..., elementN)
4.6.1arr.unshift(element1, ..., elementN)
4.8.4arr.toLocalString([locales[,options]])
4.9.1 arr.concat(value1[, value2[, ...[, valueN]]])
4.9.2 arr.slice([begin[, end]])
4.9.3 array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
4.10.1arr.copyWithin(target[, start[, end]])
4.10.2arr.fill(value[, start[, end]])
4.11.1arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
4.11.2arr.map(callback(currentValue [, index [, array]])[, thisArg])
4.11.3arr.filter(callback(element[, index[, array]])[, thisArg])
4.12.1arr.reuce(callbackFn(previousValue,currentValue[, currentIndex[, array]])[, thisArg])
4.12.1arr.reuceRight(callback(accumulator,element[, index[, array]])[, thisArg])
4.13.2arr.flatMap(function callback(currentValue[,index[,array]]){}[,thisArg])
1.静态属性
1.1Array[Symbol.species]
- 返回Array对象的构造函数(也就是原型constructor上的构造函数)
console.log(Array[Symbol.species])//ƒ Array() { [native code] }
console.log(Array[Symbol.species]===Array.prototype.constructor)//true
2.实例属性
2.1length
- 数组中元素的个数
let arr=[1,5,2]
console.log(arr.length)//3
3.静态方法
3.1Array.isArray(obj)
- 用于确定传递的值是否是一个Array
console.log(Array.isArray([]))//true
console.log(Array.isArray(new Array()))//true
console.log(Array.isArray(Array.prototype))//true
console.log(Array.isArray())//false
console.log(Array.isArray({}))//false
console.log(Array.isArray(null))//false
console.log(Array.isArray(undefined))//false
注意:其实Array.prototype也是一个数组
3.2Array.of(element0[, element1[, ...[, elementN]]])
- 创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。(当只有一个参数且为number类型时,会自动将其设置成为length,而不是单个元素,所以没法创建一个数组长度为1的含有number的数组)
console.log(Array.of(7))//[7]
console.log(Array.of(7,5,4))//[7,5,4]
Array(7)是创建一个长度为7的空数组,传入一个正数数值参数的时候默认指定数组的长度。那如果我们就是想创建一个具有单个元素7的数组怎么办呢,Array.of()为我们提供了解决办法。
而Array.of(7)是创建一个具有单个元素7的数组。
3.3Array.from(arrayLike[, mapFn[, thisArg]])
- 对一个类数组对象或者可迭代对象创建一个新的,浅拷贝的数组实例。
- arrayLike:想要转换成数组的伪数组对象或可迭代对象。
- mapFn:可选参数,如果指定了该参数,新数组中的每个元素会执行该回调函数。相当于Array.from(arrayLike).map(mapFn,thisArg),所以其性能比map差。
- thisArg:可选参数,执行回调函数
mapFn
时this
对象。
可迭代对象即为实现了iterable接口的对象,如数组,字符串,映射,集合,arguments,NodeList等DOM集合类型。
伪数组对象如arguments对象和NodeList等DOM集合类型,有length属性和若干索引属性,但是没有数组的方法,故叫伪数组对象。
将字符串转换为字符串数组
console.log(Array.from("abc2hyu"))//["a","b","c","2","h","y","u"]
数组的合并去重
function combine(){
let arr=[].concat.apply([],arguments)
return Array.from(new Set(arr))
}
4.实例方法
4.1查询具体元素的下标
4.1.1arr.indexOf(searchElement[, fromIndex])
- 返回指定元素在数组中的第一个索引,从数组前面往后面找,如果不存在,则返回-1。
- searchElement:待查询的元素
- fromIndex:可选参数,表示开始查找的位置,可正可负,但不会改变从前到后的查找顺序,如果该正数索引值大于或等于数组长度,或者负数转换成正数之后大于或等于数组长度,那么整个数组都不会被查询。正数和负数转换后要小于或等于索引值,(转换后是负数也是小于或等于索引值,也会被查询到),才能查询到数组。(如果长度为3的数组,-1就相当于是倒数第一个也就是第三个,所以转换公式为length+负数)。
let array = [2, 5, 9];
console.log(array.indexOf(2,0)); // 0
console.log(array.indexOf(2,1)); // -1
console.log(array.indexOf(9,3)); // -1
console.log(array.indexOf(9,2)); // 2
console.log(array.indexOf(9,-100)); // 2
console.log(array.indexOf(9,-1)); // 2
4.1.2arr.lastIndexOf(searchElement[, fromIndex])
- 返回指定元素在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从
fromIndex
处开始。
- searchElement:待查询的元素
- fromIndex:可选参数,表示开始查找的位置,可正可负,但不会改变从后到前的查找顺序,如果该负数转换成正数之后还是负数,那么整个数组都不会被查询。正数和正数转换后要大于或等于0,(转换后是负数大于索引值,也会被全部查询到),才能查询到数组。(如果长度为3的数组,-1就相当于是倒数第一个也就是第三个,所以转换公式为length+负数)。
let array = [2, 5,2, 9];
console.log(array.lastIndexOf(2,1)); // 0
console.log(array.lastIndexOf(2)); // 2
console.log(array.lastIndexOf(2,-3)); // 0
console.log(array.lastIndexOf(2,-9)); // -1
console.log(array.lastIndexOf(2,100)); // 2
4.1.3arr.includes(valueToFind[, fromIndex])
- 判断一个数组是否包含一个指定的值,根据情况,如果包含则返回
true
,否则返回false
。
-
valueToFind
:需要查找的元素值。 - fromIndex:可选参数,表示开始查找的位置,可正可负,但不会改变从前到后的查找顺序,如果该正数索引值大于或等于数组长度,或者负数转换成正数之后大于或等于数组长度,那么整个数组都不会被查询。正数和负数转换后要小于或等于索引值,(转换后是负数也是小于或等于索引值,也会被查询到),才能查询到数组。(如果长度为3的数组,-1就相当于是倒数第一个也就是第三个,所以转换公式为length+负数)。
let array = [2, 5,2, 9];
console.log(array.lastIndexOf(2,1)); // 0
console.log(array.lastIndexOf(2)); // 2
console.log(array.lastIndexOf(2,-3)); // 0
console.log(array.lastIndexOf(2,-9)); // -1
console.log(array.lastIndexOf(2,100)); // 2
4.2查询满足条件的具体元素
4.2.1arr.find(callback[, thisArg])
- 返回数组中满足提供的测试函数的第一个元素的值。否则返回undefined。
callback
:在数组每一项上执行的函数,接收 3 个参数:element
:当前遍历到的元素。index:
可选参数当前遍历到的索引。array:
可选参数,数组本身。
thisArg:
可选参数执行回调时用作this
的对象。
需求:查找user中是否有age为18的用户,有则返回第一个用户的信息,否则返回undefined
let user = [
{ name: "ct", age: 18 },
{ name: "cx", age: 19 },
{ name: "ca", age: 18 }
]
console.log(user.find((value) => { return value.age === 18 }))//{ name: "ct", age: 18 }
4.2.2arr.findIndex(callback[, thisArg])
-
返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。
callback
:在数组每一项上执行的函数,接收 3 个参数:element
:当前遍历到的元素。index:
可选参数当前遍历到的索引。array:
可选参数,数组本身。
thisArg:
可选参数执行回调时用作this
的对象。
需求:查找user中是否有age为18的用户,有则返回第一个用户的下标,否则返回-1
let user = [
{ name: "ct", age: 18 },
{ name: "cx", age: 19 },
{ name: "ca", age: 18 }
]
console.log(user.findIndex((value) => { return value.age === 18 }))//0
4.3查询是否存在满足条件的元素
4.3.1arr.some(callback[, thisArg])
- 测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个布尔值
callback
:在数组每一项上执行的函数,接收 3 个参数:element
:当前遍历到的元素。index:
可选参数当前遍历到的索引。array:
可选参数,数组本身。
thisArg:
可选参数执行回调时用作this
的对象。
需求:查找user中是否存在age为18的用户,有则返回true,否则返回false
let user = [
{ name: "ct", age: 18 },
{ name: "cx", age: 19 },
{ name: "ca", age: 18 }
]
console.log(user.some((value) => { return value.age === 18 }))//true
4.4查询是否所有元素都满足条件
4.4.1arr.every(callback[, thisArg])
- 测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
callback
:在数组每一项上执行的函数,接收 3 个参数:element
:当前遍历到的元素。index:
可选参数当前遍历到的索引。array:
可选参数,数组本身。
thisArg:
可选参数执行回调时用作this
的对象。
需求:查找user中是否所有的用户age都为18,是则返回true,否则返回false
let user = [
{ name: "ct", age: 18 },
{ name: "cx", age: 19 },
{ name: "ca", age: 18 }
]
console.log(user.every((value) => { return value.age === 18 }))//true
4.5添加/删除数组元素(尾)
4.5.1arr.push(element1, ..., elementN)
- 将一个或多个元素添加到数组的末尾,并返回该数组的新长度。
- 可被call或者apply用于类数组对象,如果不包含length属性,或者length属性不能被转换为一个数值,则将length置为0。
-
elementN
被添加到数组末尾的元素。
需求:向arr数组中添加元素"cx",将arr和arr1合并
let arr = [1, 2, 3]
let arr1 = [8, 9, 10]
console.log(arr.push("cx"))//4
console.log(arr)//[1,2,3,"cx"]
// 通常与apply,call一起使用
// 合并数组
console.log(Array.prototype.push.apply(arr, arr1))//7
console.log(arr)//[1,2,3,"cx",8,9,10]
注意:此处的合并数组和前面Array.from()中的合并数组实现不一样,请多多留心。
push
方法具有通用性。该方法和 call(),apply()一起使用时,可应用在类似数组的对象上。也可以像数组一样使用对象,借用call,将对象作为this传进去,让其以为我们在操作数组。
var obj = {
length: 0,
addElem: function addElem(elem) {
[].push.call(this, elem);
}
};
obj.addElem({});
obj.addElem({});
console.log(obj.length);//2
console.log(obj);//{0:{},1:{},length:2,addElem:f}
- 注意:尽管 obj 不是数组,但是 push 方法成功地使 obj 的 length 属性增长了,就像我们处理一个实际的数组一样。
4.5.2arr.pop()
- 从数组中删除最后一个元素,并返回该元素的值。此方法会更改数组的长度。
- 可被call或者apply用于类数组对象,如果不包含length属性,或者length属性不能被转换为一个数值,则将length置为0,并返回undefined。
需求:向arr数组删除最后一个元素
let arr = [1, 2, 9]
console.log(arr.pop())//9
注意:从数组中删除的元素(当数组为空时返回 undefined)。
4.6添加/删除数组元素(头)
4.6.1arr.unshift(element1, ..., elementN)
- 将一个或多个元素添加到数组的头部,并返回该数组的新长度。
- 可被call或者apply用于类数组对象,但对于没有length属性的对象,调用该方法可能没有任何结果。
elementN
被添加到数组头部的元素
需求:向arr数组头部中添加元素"cx","ct"
let arr = [1, 2, 3]
console.log(arr.unshift("cx","ct"))//5
console.log(arr)//["cx","ct",1,2,3]
4.6.2arr.shift()
- 从数组中删除第一个元素,并返回该元素的值。此方法会更改数组的长度。
- 可被call或者apply用于类数组对象,但对于没有length属性的对象,调用该方法可能没有任何结果。
需求:向arr数组删除第一个元素
let arr = [1, 2, 9]
console.log(arr.pop())//1
4.7数组的排序方法
4.7.1arr.reverse()
- 数组中元素的位置颠倒,并返回该数组的引用。该方法会改变原数组。
- 可被call或者apply用于类数组对象
let arr = [1, 2, 3]
console.log(arr.reverse())//[3,2,1]
4.7.2arr.sort()
- 用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的
- 排序后的数组。请注意,数组已原地排序,并且不进行复制。
compareFunction
可选参数:用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的Unicode位点进行排序。
firstEl
:第一个用于比较的元素。
secondEl
:第二个用于比较的元素。
- 如果没有指明
compareFunction
,那么元素会按照转换为的字符串的诸个字符的Unicode位点进行排序。 - 如果指明了
compareFunction
,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:
- 如果
compareFunction(a, b)
小于 0 ,那么 a 会被排列到 b 之前; - 如果
compareFunction(a, b)
等于 0 , a 和 b 的相对位置不变。备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本); - 如果
compareFunction(a, b)
大于 0 , b 会被排列到 a 之前。
let arr2=[20,5,71,6]
console.log(arr2.sort())//[20,5,6,71]
console.log(arr2.sort((a,b)=>{return a-b}))//升序排列[5,6,20,71]
数组对象也可以按照某个属性进行排序
var items = [
{ name: 'Edward', value: 21 },
{ name: 'Sharpe', value: 37 },
{ name: 'And', value: 45 },
{ name: 'The', value: -12 },
{ name: 'Magnetic' },
{ name: 'Zeros', value: 37 }
];
items.sort(function (a, b) {
return (a.value - b.value)
});
4.8数组的转换方法
不只是数组,所有的对象都有下列三个方法toString(),toLocalString(),valueOf()方法。
4.8.1arr.valueOf()
- 数组没有重写这个方法,这个方法还是对象身上的,用于返回数组的原始值
let arr3=[2,54,21]
console.log(arr3.valueOf())//[2,54,21]
4.8.2arr.toString()
- 数组重写了这个方法,用于返回数组中每个值的等效字符串拼接而成的以逗号分割的字符串
let arr3=[2,54,21]
console.log(arr3.toString())//'2,54,21'
注意:有没有觉得我们这个方法和join方法很像,同样是返回一个字符串,但是我们的join方法可以指定字符串中间的分割符号。
4.8.3arr.join([separator])
- 将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。
- 可被call或者apply用于类数组对象。
separator
:可选参数,指定一个字符串来分隔数组的每个元素。如果需要,将分隔符转换为字符串。如果缺省该值,数组元素用逗号(,
)分隔。如果separator
是空字符串(""
),则所有元素之间都没有任何字符。
var a = ['Wind', 'Rain', 'Fire'];
var myVar1 = a.join(); // myVar1的值变为"Wind,Rain,Fire"
var myVar2 = a.join(', '); // myVar2的值变为"Wind, Rain, Fire"
var myVar3 = a.join(' + '); // myVar3的值变为"Wind + Rain + Fire"
var myVar4 = a.join(''); // myVar4的值变为"WindRainFire"
- 注意:一个所有数组元素连接的字符串。如果
arr.length
为0,或者元素为undefined
或null
,它会被转换为空字符串。
4.8.4arr.toLocalString([locales[,options]])
- 返回一个字符串表示数组中的元素。数组中的元素将使用各自的
toLocaleString
方法转成字符串,这些字符串将使用一个特定语言环境的字符串(例如一个逗号 ",")隔开。
locales
:可选参数,带有BCP 47语言标记的字符串或字符串数组,关于locales
参数的形式与解释,请看Intl页面。options
:可选参数,一个可配置属性的对象。
var prices = ['¥7', 500, 8123, 12];
console.log(prices.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }));
// "¥7,¥500,¥8,123,¥12"
这个方法里面还有很多配置,很复杂,可以去看对应的官网。
- 注意:对于数字 Number.prototype.toLocaleString(),对于日期Date.prototype.toLocaleString().,对于对象Object.prototype.toLocaleString(),数组中的元素将会使用各自的toLocalString方法。
4.9数组的操作方法
4.9.1 arr.concat(value1[, value2[, ...[, valueN]]])
- 用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
- 数组和/或值,将被合并到一个新的数组中。
- 如果省略了所有
valueN
参数,则concat
会返回调用此方法的现存数组的一个浅拷贝。
var arr = ['a', 'b', 'c'];
var arr1 = arr.concat(1, [2, 3]);
console.log(arr1);// ['a', 'b', 'c', 1, 2, 3]
注意:返回一个浅拷贝,它包含与原始数组相结合的相同元素的副本。 原始数组的元素将复制到新数组.
4.9.2 arr.slice([begin[, end]])
- 方法返回一个新的数组对象,这一对象是一个由
begin
和end
决定的原数组的浅拷贝(包括begin
,不包括end
)。原始数组不会被改变。
-
begin:
可选参数,提取起始处的索引(从0
开始),从该索引开始提取原数组元素。-
如果该参数为负数,则转换为正数,length+begin。
-
如果省略
begin
,则slice
从索引0
开始。 -
如果
begin
超出原数组的索引范围,则会返回空数组。
-
end
:可选参数,提取终止处的索引(从0
开始),在该索引处结束提取原数组元素。- 如果该参数为负数, 则转换为正数,length+begin。
- 如果
end
被省略或者大于或等于数组长度,则slice
会一直提取到原数组末尾。
4.9.3 array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
- 通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
-
start:
指定修改的开始位置(从0计数)。- 如果超出了数组的长度,则从数组末尾开始添加内容;
- 如果是负值,则转换为正数,length+begin,如果转换后还是为负数,则表示开始位置为0.
deleteCount
:可选参数,整数,表示要移除的数组元素的个数。- 如果
deleteCount
被省略了,或者它的值大于等于array.length - start
(也就是说,如果它大于或者等于start
之后(包括start)的所有元素的数量),那么start和
之后数组的所有元素都会被删除。 - 如果
deleteCount
是 0 或者负数,则不移除元素。这种情况下,至少应添加一个新元素。
- 如果
item1, item2, ...:
可选参数,要添加进数组的元素,从start
位置左侧开始添加。如果不指定,则splice()
将只删除数组元素。
var prices = ['¥7', 500, 8123, 12];
prices.splice(0,-1,8,9)
console.log(prices)//[8, 9, '¥7', 500, 8123, 12]
prices.splice(0,2)
console.log(prices)//['¥7', 500, 8123, 12]
4.10数组的复制填充方法
4.10.1arr.copyWithin(target[, start[, end]])
- 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。
- 可被call或者apply用于类数组对象。
-
target:0 为基底的索引,复制序列到该位置。
-
如果是负值,则转换为正数,length+begin,如果转换后还是为负数,则表示开始位置为0.
-
如果
target
大于等于arr.length
,将不会发生拷贝。 -
如果
target
在start
之后,复制的序列将被修改以符合arr.length
。
-
-
start:
0 为基底的索引,开始复制元素的起始位置。- 如果
start
被忽略,copyWithin
将会从0开始复制。 - 如果是负值,则转换为正数,length+begin,如果转换后还是为负数,则表示开始位置为0.
- 如果
- end:0 为基底的索引,开始复制元素的结束位置。
- 如果
end
被忽略,copyWithin
方法将会一直复制至数组结尾(默认为arr.length
)。 - 如果是负值,则转换为正数,length+begin,如果转换后还是为负数,则表示开始位置为0.
copyWithin
将会拷贝到该位置,但不包括end
这个位置的元素。
- 如果
[1, 2, 3, 4, 5].copyWithin(-2)
// [1, 2, 3, 1, 2]
[1, 2, 3, 4, 5].copyWithin(0, 3)
// [4, 5, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
// [4, 2, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(-2, -3, -1)
// [1, 2, 3, 3, 4]
4.10.2arr.fill(value[, start[, end]])
- 用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
- 可被call或者apply用于类数组对象。
-
value
:用来填充数组元素的值。 -
start:
可选参数起始索引,默认值为0。-
如果是负值,则转换为正数,length+begin,如果转换后还是为负数,则表示开始位置为0.
-
-
end
:可选参数终止索引,不包括终止索引,默认值为this.length
。-
如果是负值,则转换为正数,length+begin。
-
[1, 2, 3].fill(4); // [4, 4, 4]
[1, 2, 3].fill(4, 1); // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2); // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1); // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3); // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2); // [4, 2, 3]
4.11数组的迭代方法
主要有forEach,map,filter,some和evey我们在前面已经说过了,不再赘述了。
4.11.1arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
- 方法对数组的每个元素执行一次给定的函数。
- 没有返回值,或者说返回值为undefined,并且不可链式调用
- 相当于是浅调用,如果在callback里面改变基本数据类型是不能生效的,改变引用类型里面的值可以生效。
- 可被call或者apply用于类数组对象。
callback
:为数组中每个元素执行的函数,该函数接收一至三个参数:array
可选参数正在操作的数组。index:
可选参数,数组中正在处理的当前元素的索引。currentValue
:数组中正在处理的当前元素。
thisArg
:可选参数。当执行回调函数callback
时,用作this
的值。想要实现这种效果,就不能用箭头函数当回调函数,因为箭头函数没有this,也不能通过call,apply,bind改变内部的this,其this是由外部定义的执行上下文的this决定的。- 值为
null
或undefined或者省略了
,this
则指向全局对象 thisArg
参数有值,则每次callback
函数被调用时,this
都会指向thisArg
参数
- 值为
forEach()
遍历的范围在第一次调用callback
前就会确定。- 调用
forEach
后添加到数组中的项不会被callback
访问到。(增) - 没有访问的项被删除的话不会被遍历到。如果已访问的元素在迭代时被删除了或者未被初始化(例如使用 shift()),之后的元素将被跳过。(删)
- 如果已经存在的值被改变,则传递给
callback
的值是forEach()
遍历到他们那一刻的值。(改) - 上面callback的这些情况都是因为forEach没有复制原始数组副本而导致的。
var words = ['one', 'two', 'three', 'four'];
words.forEach(function(word) {
console.log(word);
if (word === 'two') {
words.shift();
}
});
//删除后,数组整个往前移动,变成["two","three","four"],而索引1和2已经被遍历过,所以会跳过,所以three不会被打印
// one
// two
// four
4.11.2arr.map(callback(currentValue [, index [, array]])[, thisArg])
- 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值(包括undefined)组成。
- 可被call或者apply用于类数组对象。
callback
:为数组中每个元素执行的函数,该函数接收一至三个参数:array
可选参数正在操作的数组。index:
可选参数,数组中正在处理的当前元素的索引。currentValue
:数组中正在处理的当前元素。
thisArg
:可选参数。当执行回调函数callback
时,用作this
的值。想要实现这种效果,就不能用箭头函数当回调函数,因为箭头函数没有this,也不能通过call,apply,bind改变内部的this,其this是由外部定义的执行上下文的this决定的。- 值为
null
或undefined或者省略了
,this
则指向全局对象 thisArg
参数有值,则每次callback
函数被调用时,this
都会指向thisArg
参数
- 值为
map()
遍历的范围在第一次调用callback
前就会确定。- 调用 map后添加到数组中的项不会被
callback
访问到。(增) - 没有访问的项被删除的话不会被遍历到。如果已访问的元素在迭代时被删除了或者未被初始化(例如使用 shift()),之后的元素将被跳过。(删)
- 如果已经存在的值被改变,则传递给
callback
的值是 map()
遍历到他们那一刻的值。(改)
var numbers = [1, 4, 9];
var doubles = numbers.map(function(num) {
return num * 2;
});
// doubles数组的值为: [2, 8, 18]
// numbers数组未被修改: [1, 4, 9]
4.11.3arr.filter(callback(element[, index[, array]])[, thisArg])
- 创建一个新数组,也就是不改变原数组, 其包含通过所提供函数实现的测试的所有具体元素。
callback
:为数组中每个元素执行的函数,该函数接收一至三个参数:array
可选参数正在操作的数组。index:
可选参数,数组中正在处理的当前元素的索引。currentValue
:数组中正在处理的当前元素。
thisArg
:可选参数。当执行回调函数callback
时,用作this
的值。想要实现这种效果,就不能用箭头函数当回调函数,因为箭头函数没有this,也不能通过call,apply,bind改变内部的this,其this是由外部定义的执行上下文的this决定的。- 值为
null
或undefined或者省略了
,this
则指向全局对象 thisArg
参数有值,则每次callback
函数被调用时,this
都会指向thisArg
参数
- 值为
filter()
遍历的范围在第一次调用callback
前就会确定。- 调用 filter后添加到数组中的项不会被
callback
访问到。(增) - 没有访问的项被删除的话不会被遍历到。如果已访问的元素在迭代时被删除了或者未被初始化(例如使用 shift()),之后的元素将被跳过。(删)
- 如果已经存在的值被改变,则传递给
callback
的值是 filter()
遍历到他们那一刻的值。(改)
function isBigEnough(element) {
return element >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]
4.12数组的归并方法
reduce和reduceRight
4.12.1arr.reduce(callbackFn(previousValue
,currentValue
[, currentIndex
[, array]])[, initialValue
])
- 方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。
callbackFn
:包含四个参数,reduce
对于数组中第一个元素之后的每一个元素,按升序各调用一次回调函数。(故只有一个参数且没提供initialValue,或者空数组提供了initialValue但是数组为空,那么此唯一值被返回,且callbackFn不执行)previousValue
:上一次调用callbackFn
时的返回值。currentValue
:数组中正在处理的元素。currentIndex
:可选参数,数组中正在处理的元素的索引。若指定了初始值initialValue
,则起始索引号为 0,否则从索引 1 起始。array
:可选参数,用于遍历的数组。
initialValue
可选参数:作为第一次调用callbackFn
函数时参数 previousValue 的值。- 若指定了初始值
initialValue
,则previousValue
即为initialValue的值,然后currentValue
则将使用数组第一个元素; - 否则
previousValue
将使用数组第一个元素,而currentValue
将使用数组第二个元素。 - 如果不给出初始值,则需保证数组不为空。
否则,在空数组上调用reduce
或reduceRight
且未提供初始值(例如[].reduce( (acc, cur, idx, arr) => {} )
)的话,会导致类型错误TypeError: reduce of empty array with no initial value
。
- 若指定了初始值
let sum = [0, 1, 2, 3].reduce(function (previousValue, currentValue) {
return previousValue + currentValue
}, 0)
// sum is 6
4.12.1arr.reduceRight(callback(accumulator,element[, index[, array]])[, initialValue
])
- 方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。
callback
:包含四个参数,reduce
对于数组中第一个元素之后的每一个元素,按升序各调用一次回调函数。(故只有一个参数且没提供initialValue,或者空数组提供了initialValue但是数组为空,那么此唯一值被返回,且callback不执行)- accumulator:上一次调用
callback
时的返回值。 - element:数组中正在处理的元素。
- index:可选参数,数组中正在处理的元素的索引。若指定了初始值
initialValue
,则起始索引号为 0,否则从索引 1 起始。 array
:可选参数,用于遍历的数组。
- accumulator:上一次调用
initialValue
可选参数:作为第一次调用callback
函数时参数 previousValue 的值。- 若指定了初始值
initialValue
,则accumulator即为initialValue的值,然后
element则将使用数组最后一个元素; - 否则 accumulator将使用数组最后一个元素,而 element将使用数组倒数第二个元素。
- 如果不给出初始值,则需保证数组不为空。
否则,在空数组上调用reduce
或reduceRight
且未提供初始值(例如[].reduce( (acc, cur, idx, arr) => {} )
)的话,会导致类型错误TypeError: reduce of empty array with no initial value
。
- 若指定了初始值
var sum = [0, 1, 2, 3].reduceRight(function(a, b) {
return a + b;
});
// sum is 6
reduce和reduceRight只是遍历索引的顺序不一样,reduce是升序遍历索引,reduceRight是降序遍历索引。
关于initialValue和arr的值在这做个总结
- 如果arr为空数组和initialValue没有指定,则会报错如下:
- Uncaught TypeError: Reduce of empty array with no initial value
- at Array.reduceRight (<anonymous>)
- Uncaught TypeError: Reduce of empty array with no initial value
- 如果arr有一个元素或者initialValue有一个元素,则直接返回这个元素作为最后的值,并且不会调用回调函数。
- 如果arr和initialValue都有一个值,则会调用一次回调函数,然后再将这个值作为最后的值。
4.13数组的扁平化方法
4.13.1arr.flat([depth])
- 会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
-
depth:
可选参数指定要提取嵌套数组的结构深度,默认值为 1。也就是数组里面有数组我就展开,但是展开后的情况我管不了。2就是数组展开后里面还有数组,我也可以展开,但是二次展开后的情况我也管不了。故depth越大,展开的层数越多。
var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
//使用 Infinity,可展开任意深度的嵌套数组
var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
//flat() 方法会移除数组中的空项:
var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]
4.13.2arr.flatMap(function callback(currentValue[,index[,array]]){}[,thisArg])
- 使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为1的 flat 几乎相同,但
flatMap
通常在合并成一种方法的效率稍微高一些。相当于arr.map.flat(1) - 返回一个新的数组,其中每个元素都是回调函数的结果,并且结构深度
depth
值为1。
callback
:可以生成一个新数组中的元素的函数,可以传入三个参数:
currentValue
:当前正在数组中处理的元素
index:
可选参数,数组中正在处理的当前元素的索引。
array:
可选参数,被调用的 map
数组
thisArg:
可选参数,执行 callback
函数时 使用的this
值。
var arr1 = [1, 2, 3, 4];
arr1.map(x => [x * 2]);
// [[2], [4], [6], [8]]
arr1.flatMap(x => [x * 2]);
// [2, 4, 6, 8]
// only one level is flattened
arr1.flatMap(x => [[x * 2]]);
// [[2], [4], [6], [8]]
4.14数组的迭代器方法
values,keys,entries方法,这三个方法目前没了解多少,稍后会完善。
数组中改变原数组的方法有splice,pop,push,shift,unshift,sort,reverse这几个方法会改变原数组,其他的方法都不会改变原数组。