在JavaScript开发实践中,开发者常会遇到各类重复性技术挑战。本文系统梳理了10个典型场景的解决方案,每个方案均包含问题背景、实现原理和完整代码示例,帮助开发者建立系统化的技术认知。
一、对象与数组的转换处理
-
对象键值对数组生成
当需要将对象属性转换为键值对数组时,可采用Object.keys()结合Array.map()的组合方案:const obj = { a: 1, b: 2 };const keyValuePairs = Object.keys(obj).map(key => [key, obj[key]]);// 输出: [['a',1], ['b',2]]
该方案通过Object.keys()获取对象属性名数组,再利用map方法将每个属性名映射为[key, value]形式的子数组。时间复杂度为O(n),适用于任意可枚举对象。
-
数组虚假值过滤
处理包含null/undefined/0/“”等虚假值的数组时,推荐使用filter方法结合Boolean转换:const arr = [0, 1, false, 2, '', 3, null, undefined];const filtered = arr.filter(Boolean);// 输出: [1, 2, 3]
Boolean函数作为回调时,会自动将元素转换为布尔值进行判断。相较于手动编写条件判断,此方案更简洁且不易出错。
二、日期与数值计算
-
日期差值计算
精确计算两个日期之间的天数差需考虑时区问题:function getDayDiff(startDate, endDate) {const diffTime = Math.abs(endDate - startDate);return Math.ceil(diffTime / (1000 * 60 * 60 * 24));}// 使用示例const start = new Date('2023-01-01');const end = new Date('2023-01-10');console.log(getDayDiff(start, end)); // 输出: 9
该方案通过绝对值处理确保时间差为正数,使用Math.ceil向上取整避免小数天数。对于跨时区场景,建议先使用UTC方法统一时区。
-
数组差异比较
处理大型数组差异时,Set数据结构可显著提升性能:function arrayDifference(arr1, arr2) {const set = new Set(arr2);return arr1.filter(x => !set.has(x));}// 使用示例const arrA = [1, 2, 3, 4];const arrB = [3, 4, 5, 6];console.log(arrayDifference(arrA, arrB)); // 输出: [1, 2]
Set的has方法时间复杂度为O(1),相比传统双重循环的O(n²)方案,在处理10万级数据时性能可提升数百倍。
三、数组高级操作
-
数组转CSV格式
处理多维数组转CSV时需注意特殊字符转义:function arrayToCSV(data, delimiter = ',') {return data.map(row =>row.map(cell =>typeof cell === 'string' && cell.includes(delimiter)? `"${cell}"`: cell).join(delimiter)).join('\n');}// 使用示例const data = [['Name', 'Age', 'City'],['John,Doe', 30, 'New York'],['Jane Smith', 25, 'Los Angeles']];console.log(arrayToCSV(data));
该方案自动处理包含分隔符的字符串字段,通过添加引号确保CSV格式正确性。对于更复杂场景,建议使用专用库如PapaParse。
-
元素出现次数统计
使用reduce方法实现元素计数器:function countOccurrences(arr, target) {return arr.reduce((acc, curr) =>curr === target ? acc + 1 : acc, 0);}// 使用示例const numbers = [1, 2, 3, 2, 4, 2, 5];console.log(countOccurrences(numbers, 2)); // 输出: 3
此方案时间复杂度为O(n),空间复杂度为O(1)。如需统计所有元素出现次数,可修改为返回对象形式。
四、字符串处理技巧
-
字符串首字母大写
实现标题格式转换的完整方案:function capitalizeFirstLetter(str) {if (!str) return str;return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();}// 使用示例console.log(capitalizeFirstLetter('hello WORLD')); // 输出: "Hello world"
该方案同时处理了空字符串和后续字母小写化需求。对于多单词字符串,可结合split/map/join实现每个单词首字母大写。
-
数组最大值查找
处理可能包含非数字元素的数组:function findMaxNumber(arr) {const numericArr = arr.filter(item => typeof item === 'number' && !isNaN(item));return numericArr.length ? Math.max(...numericArr) : undefined;}// 使用示例const mixedArr = [1, 'a', 5, null, 3, undefined];console.log(findMaxNumber(mixedArr)); // 输出: 5
此方案先过滤非数字元素,再使用扩展运算符展开数组。对于超大型数组,建议改用reduce方法避免栈溢出。
五、实用工具函数
-
数组平均值计算
处理包含非数值元素的健壮方案:function calculateAverage(arr) {const numbers = arr.filter(item => typeof item === 'number' && !isNaN(item));return numbers.length? numbers.reduce((sum, val) => sum + val, 0) / numbers.length: NaN;}// 使用示例const data = [1, 2, 'a', 3, null, 4];console.log(calculateAverage(data)); // 输出: 2.5
该方案通过预过滤确保计算准确性,空数组时返回NaN符合IEEE 754标准。
-
JSON有效性验证
生产环境级验证方案:function isValidJson(str) {try {JSON.parse(str);return true;} catch (e) {if (e instanceof SyntaxError) {return false;}throw e; // 重新抛出非语法错误}}// 使用示例console.log(isValidJson('{"name":"John"}')); // trueconsole.log(isValidJson('{name:"John"}')); // false
此方案严格区分语法错误和其他异常,避免将网络错误等误判为无效JSON。对于大文件验证,建议使用流式解析方案。
本文介绍的解决方案均经过实际项目验证,开发者可根据具体场景选择合适方法。建议建立个人工具库收藏这些实用函数,通过持续积累提升开发效率。在复杂项目开发中,建议结合TypeScript进行类型约束,进一步提升代码可靠性。