关于 Array 的 API 有好多,这里从纯函数出发来说明白。
什么是纯函数
要想成为纯函数必须满足以下两个条件:
- 函数返回的结果只依赖于它传递的参数
- 函数执行过程中没有产生任何的副作用
在这里,我们针对于数组我们可以这样理解纯函数:使用后不改变原本的数组即没有产生副作用并且会返回一个新的数组。
Array 纯函数
下面 API 使用后将返回一个新的数组:
- concat:连接数组
- filter:返回符合过滤条件的数组
- map:每个元素都执行规则
- slice:切片,返回选定的数组
Array 非纯函数
- pop:弹出末尾元素,返回元素
- push:末尾添加元素,返回新数组的长度
- unshift:首部添加元素,返回新数组的长度
- shift:首部弹出元素,返回元素
- some:只要有一个元素符合条件立即返回 true
- every:所有元素均符合条件才返回 true
- forEach:遍历每个元素,不返回任何值
- splice:剪接
顺带介绍下 split 和 join
- split:分割数组
- join:拼接数组
let a = 'a-b-c-d-e-f-g';
const b = a.split('-');
console.log(b); // ['a', 'b', 'c', 'd', 'e', 'f', 'g']
console.log(b.join('-')); // a-b-c-d-e-f-g
slice 和 splice 的区别
三点出发:
- 功能不同
- 参数不同
- 返回值不同
- 是否是纯函数
slice 是纯函数,不会影响原有数组,而是返回一个新的数组。除此之外,slice 的第一个参数代表的是起始位置,第二个参数代表的是结束位置,返回结果不包括结束位置的元素。
const arr1 = [10, 20, 30, 40, 50, 60];
const arr2 = arr1.slice(1, 3);
console.log(arr2); // [20, 30]
splice 不是纯函数,它会改变原有数组,返回的剪下来元素形成的的数组,可以利用 splice 插入元素,它的第一个参数为起始位置,第二个参数为剪接的长度(默认为1),第三个及其后面的参数为要插入的元素。
const arr1 = [10, 20, 30, 40, 50, 60];
const arr2 = arr1.splice(1, 3, 'abc', 'efg');
console.log(arr1); // [ 10, 'abc', 'efg', 50, 60 ]
console.log(arr2); // [ 20, 30, 40 ]
一道 map 网红题
[0, 1, 2, 3, 10, 100].map(parseInt)
其实这道题并不难,只不过是你知道不知道的问题,如果你对《JavaScript高级程序设计》的内容有印象的话,就可以发现有讲过 parseInt 的第二个参数决定了进制。
将 [0, 1, 2, 3, 10, 100].map(parseInt) 拆开得到:
const arr = [0, 1, 2, 3, 10, 100].map((value, index) => {
return parseInt(value, index);
})
console.log(arr); // [ 0, NaN, NaN, NaN, 4, 25 ]
首先传入 0 ,0 在 parseInt 表示的是 10 进制,所以这里第一个元素输出 0。
第二个元素 1 ,index 为 1 决定了 parseInt 为 1 进制,parseInt 中即使你是 0 ,1 进制中也输出 NaN。
第三个元素 2, index 为 2 决定了 parseInt 为 2 进制,超出了 2 进制范围,输出 NaN。
第四个元素 3, index 为 3 决定了 parseInt 为 3 进制,超出了 3 进制范围,输出 NaN。
第五个元素 10,index 为 4 决定了 parseInt 为 4 进制,根据进制计算,输出 1*4 + 0 = 4。
第六个元素 100,index 为 5 决定了为 5 进制,根据进制计算,输出 5^2 + 0 + 0 = 25。