前言
JavaScript 作为一门面向对象的编程语言,数组的使用在日常代码中非常常见。然而在开发过程中不可避免地会遇到一些问题,例如数组方法API调用错误等等。 而随着ES12的推出,新的数组方法中也存在一些错误。本文将探讨ES12中的数组方法错误及其解决方法。
列表
下面将列出ES12中常见的数组方法错误:
1. Array#flat
当使用Array#flat
方法进行拍平嵌套数组时,如果嵌套的层数大于指定的展开深度时会出现错误。在 Array#flat
中,可以指定一个可选参数(展开深度),但如果递归深度超过了这个数值,该数组方法将会变得不再适用,代码如下:
const arr1 = [1, 2, [3, 4, [5, 6]]]; arr1.flat(1); // [1, 2, 3, 4, [5,6]] arr1.flat(2); // [1, 2, 3, 4, 5, 6] arr1.flat(3); // [1, 2, 3, 4, 5, 6] arr1.flat(Infinity); // [1, 2, 3, 4, 5, 6] arr1.flat(4); // TypeError: Maximum call stack size exceeded
2. Array#flatMap
在使用 Array#flatMap
方法时返回的不是数组类型,而是一个不确定的结果,可能是数组、也可能是单独的元素。这通常会导致调用 Array#flat
方法之后出现问题,代码如下:
// javascriptcn.com 代码示例 const arr2 = [1, 2, 3, [4, 5]]; console.log(arr2.flatMap(num => [num * 2, num * 3])); // [2, 3, 4, 6, 6, 9, 8, 12, 10, 15] arr2.flatMap(num => num * 2); // [2, 4, 6, 8, 10] arr2.flatMap(num => [num * 2, num * 3]); // [2, 3, 4, 6, 6, 9, 8, 12, 10, 15] arr2.flatMap(num => num * 2 + 1); // [3, 5, 7, 9, 11]
3. Array#reduce
在使用 Array#reduce
方法时,如果不指定 initialValue
时,如果数组是空的,将会抛出错误。代码如下:
const arr3 = []; arr3.reduce((prev, curr) => prev + curr); // TypeError: Reduce of empty array with no initial value arr3.reduce((prev, curr) => prev + curr, 0); // 0
4. Array#sort
在使用 Array#sort
方法时,如果待排序的数组包含 null
或 undefined
值时,将会抛出错误。代码如下:
const arr4 = [3, 5, null, undefined, 2, 5]; arr4.sort() // TypeError: Cannot convert undefined or null to object
解决方案
针对上述列出的ES12中的数组方法错误,下面提出一些解决方法及建议。
1. Array#flat
可以使用递归函数代替Array#flat
实现拍平嵌套数组,并做好防止栈溢出的处理,代码如下:
// javascriptcn.com 代码示例 function flatArray(arr, depth = 1) { return depth > 0 ? arr.reduce((acc, item) => { if (Array.isArray(item)) { acc.push(...flatArray(item, depth - 1)) } else { acc.push(item) } return acc }, []) : arr.slice() } const arr = [1, 2, [3, 4, [5, 6]]] console.log(flatArray(arr)) // [1, 2, 3, 4, 5, 6]
注意
- 代码中使用 slice() 方法克隆数组,可以避免改变原始数据
- 需要做好栈溢出的处理,可以使用尾递归或基于 Generator 功能的实现。
2. Array#flatMap
使用 Array#flatMap
方法时尽可能保证其返回值的类型为数组,并且可以在遍历阶段内使用条件语句进行数据过滤、类型转换等处理,代码如下:
// javascriptcn.com 代码示例 const arr = [1, 2, 3, 4]; const result = arr.flatMap((i) => { if (i % 2 === 0) { return [i, i ** 2]; } return i; }); console.log(result); // [1, 2, 4, 4, 3, 6]
从上面可以看出:
- 当
i
为偶数时,返回一个包含i
和i
的平方的数组。 - 当
i
为奇数时,返回原始值。
此时返回值总为数组,避免了因为返回单一值或变量而导致的错误发生。
3. Array#reduce
使用 Array#reduce
方法进行累加时,一定要指定好 initialValue
。进而避免因示例中的特殊情况而导致的错误,代码如下:
const arr = []; const sum = arr.reduce((prev, curr) => prev + curr, 0); console.log(sum); // 0
4. Array#sort
在使用 Array#sort
方法时,可以通过二次处理待排数组来避免 null
或 undefined
值的出现,代码如下:
const arr = [3, 5, null, undefined, 2, 5]; const result = arr .filter((i) => i !== null && i !== undefined) // 过滤null、undefined .sort((a, b) => a - b); // 对过滤后的数组进行排序 console.log(result); // [2, 3, 5, 5]
注意
如果数组中存在不同类型元素的情况,则可以对可能出现的不同类型进行排除并保留可比较元素。
总结
本文详细介绍了ES12中的数组方法错误及其解决方法。在日常开发中一定要注意各种语言API的错误边界,理解其使用方法及限制条件。可以通过改变写法、使用高阶函数代替等方式来解决问题。本文所探讨的方法不完全,读者可以根据实际业务场景研究其他的解决方法。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6502a53395b1f8cacdfe1a9f