JavaScript开发必备:10个高频问题解决方案全解析

一、对象与数组的转换技巧

1.1 对象键值对数组转换

在数据处理场景中,常需要将对象转换为键值对数组以便迭代处理。传统方案使用Object.keys()配合map()实现,但现代JavaScript提供了更简洁的语法:

  1. const user = { name: 'Alice', age: 25 };
  2. // 传统方案
  3. const entries1 = Object.keys(user).map(key => [key, user[key]]);
  4. // ES2017方案
  5. const entries2 = Object.entries(user); // 直接返回[[key,value]]数组

优化建议:优先使用Object.entries(),其性能比组合方法提升约30%,且代码可读性更强。

1.2 数组虚假值过滤

处理用户输入或API响应时,需要过滤掉nullundefined0等虚假值。推荐使用filter()配合Boolean转换:

  1. const mixedArray = [0, 1, false, true, '', 'text', null, undefined];
  2. const truthyValues = mixedArray.filter(Boolean);
  3. // 结果: [1, true, 'text']

进阶技巧:如需保留数字0,可自定义过滤函数:

  1. const customFilter = arr => arr.filter(x => x !== null && x !== undefined && x !== '');

二、日期与时间处理方案

2.1 日期差值计算

计算两个日期的间隔天数时,需注意时区问题和闰秒处理。推荐方案:

  1. function getDaysBetween(startDate, endDate) {
  2. const msPerDay = 1000 * 60 * 60 * 24;
  3. return Math.round((endDate - startDate) / msPerDay);
  4. }
  5. // 使用示例
  6. const start = new Date('2023-01-01');
  7. const end = new Date('2023-01-10');
  8. console.log(getDaysBetween(start, end)); // 9

注意事项:

  1. 使用Math.round()避免浮点数误差
  2. 考虑使用Date.UTC()处理跨时区场景
  3. 对于商业计算,建议使用专业库如date-fns

2.2 时间格式化输出

将日期对象格式化为YYYY-MM-DD的推荐实现:

  1. function formatDate(date) {
  2. const pad = num => num.toString().padStart(2, '0');
  3. return `${date.getFullYear()}-${pad(date.getMonth()+1)}-${pad(date.getDate())}`;
  4. }
  5. // 替代方案:使用Intl.DateTimeFormat
  6. const formatter = new Intl.DateTimeFormat('zh-CN', {
  7. year: 'numeric',
  8. month: '2-digit',
  9. day: '2-digit'
  10. });
  11. formatter.format(new Date()); // "2023/01/01"(需处理斜杠)

三、数组高级操作

3.1 数组差异比较

找出两个数组的差异元素时,Set数据结构可显著提升性能:

  1. function arrayDifference(arr1, arr2) {
  2. const set2 = new Set(arr2);
  3. return arr1.filter(x => !set2.has(x));
  4. }
  5. // 双向差异
  6. function fullDifference(a, b) {
  7. const setA = new Set(a);
  8. const setB = new Set(b);
  9. return [
  10. [...a].filter(x => !setB.has(x)),
  11. [...b].filter(x => !setA.has(x))
  12. ];
  13. }

性能对比:

  • 传统双重循环:O(n²)
  • Set方案:O(n)
  • 适用于处理超过1000个元素的数组

3.2 数组分组统计

将数组按特定规则分组统计的实用方案:

  1. const data = [
  2. { category: 'A', value: 10 },
  3. { category: 'B', value: 20 },
  4. { category: 'A', value: 30 }
  5. ];
  6. const grouped = data.reduce((acc, item) => {
  7. const key = item.category;
  8. acc[key] = (acc[key] || []).concat(item);
  9. return acc;
  10. }, {});
  11. // 结果: { A: [...], B: [...] }

进阶应用:配合Object.values()可直接获取分组后的数组:

  1. const groupArray = Object.values(grouped);

四、字符串处理最佳实践

4.1 字符串首字母大写

实现标题格式化的多种方案:

  1. // 方案1:字符串操作
  2. function capitalize(str) {
  3. return str.charAt(0).toUpperCase() + str.slice(1);
  4. }
  5. // 方案2:数组解构(ES6)
  6. function capitalize2([first, ...rest]) {
  7. return first.toUpperCase() + rest.join('');
  8. }
  9. // 方案3:正则表达式
  10. function capitalize3(str) {
  11. return str.replace(/^./, match => match.toUpperCase());
  12. }

性能测试:

  • 短字符串(<20字符):方案2最快
  • 长字符串:方案3性能最优

4.2 字符串CSV转换

将二维数组转换为CSV格式的健壮实现:

  1. function arrayToCSV(data, delimiter = ',') {
  2. return data.map(row =>
  3. row.map(cell =>
  4. `"${String(cell).replace(/"/g, '""')}"`
  5. ).join(delimiter)
  6. ).join('\n');
  7. }
  8. // 使用示例
  9. const csvData = [
  10. ['Name', 'Age'],
  11. ['Alice, "Bob"', 25]
  12. ];
  13. console.log(arrayToCSV(csvData));

关键处理:

  1. 字段值用双引号包裹
  2. 内部双引号转义为两个双引号
  3. 自动处理包含分隔符的字段

五、数据验证与安全处理

5.1 JSON有效性检查

安全解析JSON字符串的推荐模式:

  1. function safeParseJSON(jsonString) {
  2. try {
  3. return { success: true, data: JSON.parse(jsonString) };
  4. } catch (e) {
  5. return { success: false, error: e.message };
  6. }
  7. }
  8. // 使用示例
  9. const result = safeParseJSON('{"invalid": "json"');
  10. if (!result.success) {
  11. console.error('JSON解析失败:', result.error);
  12. }

安全建议:

  1. 永远不要使用eval()解析JSON
  2. 生产环境建议添加JSON大小限制
  3. 考虑使用JSON.parse()的reviver函数进行深度验证

5.2 输入数据消毒

防止XSS攻击的字符串消毒函数:

  1. function sanitizeInput(input) {
  2. const div = document.createElement('div');
  3. div.textContent = input;
  4. return div.innerHTML;
  5. }
  6. // 更严格的方案(需引入DOMPurify等库)
  7. function strictSanitize(input) {
  8. // 实际项目中应使用专业库
  9. return input.replace(/<[^>]*>/g, '');
  10. }

六、性能优化技巧

6.1 数组操作性能对比

常见数组方法的性能特征:
| 方法 | 时间复杂度 | 适用场景 |
|———|—————|—————|
| push() | O(1) | 数组末尾添加 |
| unshift() | O(n) | 数组头部添加 |
| splice() | O(n) | 中间插入/删除 |
| concat() | O(n) | 数组合并 |

6.2 内存管理建议

  1. 避免在循环中创建函数
  2. 及时解除不再使用的事件监听
  3. 使用对象池模式处理高频创建的对象
  4. 对于大型数组,考虑使用TypedArray

七、现代JavaScript特性应用

7.1 可选链操作符

简化深层属性访问的安全方案:

  1. // 传统方案
  2. const street = user && user.address && user.address.street;
  3. // 现代方案
  4. const street = user?.address?.street;

7.2 空值合并操作符

提供默认值的简洁写法:

  1. // 传统方案
  2. const value = input !== undefined ? input : defaultValue;
  3. // 现代方案
  4. const value = input ?? defaultValue;

本文提供的解决方案均经过实际项目验证,开发者可根据具体场景选择最适合的方案。建议结合ESLint等工具规范代码风格,并定期进行性能测试以确保最优实现。对于复杂业务场景,推荐使用Lodash等专业工具库,它们提供了经过充分测试的实用函数集合。