当前位置: 首页 > news >正文

《前端面试题:数组操作》

JavaScript 数组操作指南:哪些方法会改变原数组?哪些不会?(面试必备详解)

在 JavaScript 开发中,数组操作是最常用的功能之一。区分哪些方法会改变原数组(mutating methods),哪些不会(non-mutating methods) 是面试高频考点,也是避免实际开发中产生 BUG 的关键。本文将深度解析这两类方法,并附详细代码示例。


一、会改变原数组的方法(Mutating Methods)

这些方法直接修改原始数组,使用时需特别谨慎。

  1. push()
    在数组末尾添加元素,返回 新长度

    let arr = [1, 2, 3];
    arr.push(4); // 返回长度 4
    console.log(arr); // [1, 2, 3, 4] ✅ 原数组改变
    
  2. pop()
    删除数组最后一个元素,返回 被删除的元素

    let arr = [1, 2, 3];
    arr.pop(); // 返回 3
    console.log(arr); // [1, 2] ✅ 原数组改变
    
  3. shift()
    删除数组第一个元素,返回 被删除的元素

    let arr = [1, 2, 3];
    arr.shift(); // 返回 1
    console.log(arr); // [2, 3] ✅ 原数组改变
    
  4. unshift()
    在数组开头添加元素,返回 新长度

    let arr = [1, 2, 3];
    arr.unshift(0); // 返回长度 4
    console.log(arr); // [0, 1, 2, 3] ✅ 原数组改变
    
  5. splice()
    添加/删除任意位置元素,返回 被删除元素的数组

    let arr = [1, 2, 3, 4];
    arr.splice(1, 2, 'a', 'b'); // 从索引1开始删除2个元素,添加'a'、'b'
    console.log(arr); // [1, 'a', 'b', 4] ✅ 原数组改变
    
  6. sort()
    排序数组(默认按 Unicode 排序),返回 排序后的原数组

    let arr = [3, 1, 2];
    arr.sort(); // 返回 [1, 2, 3]
    console.log(arr); // [1, 2, 3] ✅ 原数组改变
    
  7. reverse()
    反转数组顺序,返回 反转后的原数组

    let arr = [1, 2, 3];
    arr.reverse(); // 返回 [3, 2, 1]
    console.log(arr); // [3, 2, 1] ✅ 原数组改变
    
  8. fill()
    填充数组(指定范围),返回 填充后的原数组

    let arr = [1, 2, 3];
    arr.fill(0, 1, 3); // 从索引1到3填充0
    console.log(arr); // [1, 0, 0] ✅ 原数组改变
    
  9. copyWithin()
    复制数组内元素到指定位置,返回 修改后的原数组

    let arr = [1, 2, 3, 4];
    arr.copyWithin(0, 2, 4); // 将索引2-4的元素复制到索引0
    console.log(arr); // [3, 4, 3, 4] ✅ 原数组改变
    

二、不会改变原数组的方法(Non-Mutating Methods)

这些方法返回新数组或新值,原始数组保持不变。

  1. concat()
    合并数组,返回 新数组

    let arr = [1, 2];
    let newArr = arr.concat([3, 4]);
    console.log(arr);    // [1, 2] ❌ 原数组不变
    console.log(newArr); // [1, 2, 3, 4]
    
  2. slice()
    截取数组片段,返回 新数组

    let arr = [1, 2, 3, 4];
    let subArr = arr.slice(1, 3); // 截取索引1-2
    console.log(arr);    // [1, 2, 3, 4] ❌ 原数组不变
    console.log(subArr); // [2, 3]
    
  3. join()
    数组转字符串,返回 字符串

    let arr = [1, 2, 3];
    let str = arr.join('-');
    console.log(arr); // [1, 2, 3] ❌ 原数组不变
    console.log(str); // "1-2-3"
    
  4. map()
    映射新数组,返回 新数组

    let arr = [1, 2, 3];
    let doubled = arr.map(x => x * 2);
    console.log(arr);    // [1, 2, 3] ❌ 原数组不变
    console.log(doubled); // [2, 4, 6]
    
  5. filter()
    过滤元素,返回 新数组

    let arr = [1, 2, 3, 4];
    let evens = arr.filter(x => x % 2 === 0);
    console.log(arr);   // [1, 2, 3, 4] ❌ 原数组不变
    console.log(evens); // [2, 4]
    
  6. reduce() / reduceRight()
    累积计算,返回 累积结果

    let arr = [1, 2, 3];
    let sum = arr.reduce((acc, cur) => acc + cur, 0);
    console.log(arr); // [1, 2, 3] ❌ 原数组不变
    console.log(sum); // 6
    
  7. find() / findIndex()
    查找元素/索引,返回 元素值或索引

    let arr = [5, 12, 8];
    let found = arr.find(x => x > 10); // 12
    console.log(arr); // [5, 12, 8] ❌ 原数组不变
    
  8. every() / some()
    逻辑判断,返回 布尔值

    let arr = [1, 2, 3];
    let allPositive = arr.every(x => x > 0); // true
    console.log(arr); // [1, 2, 3] ❌ 原数组不变
    
  9. flat() / flatMap()
    扁平化数组,返回 新数组

    let arr = [1, [2, 3]];
    let flatArr = arr.flat();
    console.log(arr);     // [1, [2, 3]] ❌ 原数组不变
    console.log(flatArr); // [1, 2, 3]
    

三、面试高频问题与陷阱解析
  1. 问题: sort()reverse() 的返回值是什么?
    答案: 它们返回修改后的原数组(不是新数组),支持链式调用(但不推荐)。

  2. 陷阱: 嵌套对象的修改
    即使使用 map()filter() 等非变异方法,若直接修改元素内的对象属性,仍会影响原数组

    let users = [{ name: 'Alice' }, { name: 'Bob' }];
    let newUsers = users.map(user => {user.name = user.name.toUpperCase(); // ❌ 错误!修改了原对象return user;
    });
    console.log(users[0].name); // 'ALICE'(原数组被污染)
    

    正确做法:

    let newUsers = users.map(user => ({...user, // 创建新对象name: user.name.toUpperCase()
    }));
    
  3. 问题: 如何在 React/Vue 中安全更新数组状态?
    答案: 使用非变异方法或创建副本:

    // React 示例:添加元素
    setList(prev => [...prev, newItem]);// Vue 示例:删除元素
    this.list = this.list.filter(item => item.id !== id);
    
  4. 问题: 如何快速判断一个方法是否改变原数组?
    技巧:

    • 返回数组长度、元素或 undefined 的方法通常改变原数组(如 push, pop)。
    • 返回新数组的方法不改变原数组(如 map, filter)。

四、总结与最佳实践
类型方法
改变原数组push, pop, shift, unshift, splice, sort, reverse, fill, copyWithin
不改变原数组concat, slice, map, filter, reduce, find, every, flat, join

最佳实践:

  1. 在函数式编程中优先使用非变异方法。
  2. 修改数组前用 [...arr]arr.slice() 创建副本。
  3. 在框架中更新状态时,永远不要直接修改原数组

掌握这些细节不仅能轻松应对面试,更能写出健壮可靠的代码。建议收藏本文并动手练习示例代码!

相关文章:

  • PID控制电机
  • springboot入门之路(二)
  • 技术赋能教师专业发展:从理论到实践的深度剖析
  • createInnerAudioContext播放不完整?
  • 榕壹云外卖跑腿系统:基于Spring Boot的开源生活服务平台技术解析
  • STM32 GPIO 寄存器开发
  • OCCT基础类库介绍:Modeling Algorithm - Topological Tools
  • 今天我想清楚了
  • 无需公网IP:Termux+手机+内网穿透实现Minecraft远程多人联机
  • 基于大数据技术的在UGC数据分析与路线推荐的研究
  • ArcGIS中利用泰森多边形法分析站点与流域占比
  • VTK知识学习(54)- 交互与Widget(五)
  • ES 索引加载 vs BulkLoad
  • function ‘as_cholmod_sparse‘ not provided by package ‘Matrix‘
  • FreeCAD创作参数化凹形和水波纹式雨水箅子
  • 意法STM32F103C8T6 单片机ARM Cortex-M3 国民MCU 电机控制到物联网专用
  • Windows系统提示“mfc140u.dll丢失”?详细修复指南,一键恢复程序运行!
  • 智能制造——解读 51页制造业数据治理主数据管理系统建设方案【附全文阅读】
  • 从零Gazebo中实现Cartographer算法建图(新目录)
  • 如何使用 mkimage 工具生成 uImage 文件(RISC-V 环境)
  • 网站软文写作要求/百度快照关键词推广
  • 浙江省专业网站制作网站建设/网站运营管理
  • 吉林建设工程信息网/百度关键词排名优化工具
  • 辽宁省网站建设/seo网络推广是干嘛的
  • iis网站模板/免费发布推广的网站
  • 用手机免费制作app软件有哪些/快速排名优化推广价格