You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何JavaScript中const无法创建不可变数组?如何实现真正的不可变数组?

理解JavaScript中const与数组可变性,以及原生实现不可变数组的方法

先给你划个核心重点:const声明的变量只是不能被重新赋值,但这和它指向的数组/对象本身是否可变完全是两码事!

为什么你的两段代码表现天差地别?

第一段:修改数组内容成功的原因

const originalArray = [0, 2, 1, 1, 1]; 
var newArray = originalArray; 
var removed = newArray.splice(0,3); 
console.log(originalArray); // 输出 [ 1, 1 ]

这里const originalArray只是锁定了originalArray这个变量的指向——它永远绑定到最初创建的那个数组对象上。但JavaScript的数组是引用类型,newArray = originalArray只是让newArray也指向同一个数组。而splice是会直接修改原数组的方法,所以操作newArray本质上就是在操作那个共享的数组,originalArray自然也会跟着变。

第二段:重新赋值失败的原因

const originalArray = []; 
originalArray = [1]; 

这里你尝试给const声明的originalArray重新赋值一个全新的数组对象,这直接违反了const的核心规则——它不允许变量的指向被更改,所以这段代码会直接抛出语法错误。

原生JavaScript实现真正不可变的数组

不需要第三方库,我们可以用这些原生方案实现数组的不可变:

  • 直接创建不可变数组:Object.freeze()
    这个方法可以冻结一个数组(本质是对象),让它无法被修改、添加或删除元素:

    const immutableArray = Object.freeze([0, 2, 1, 1, 1]);
    immutableArray.splice(0, 3); // 抛出错误:Cannot assign to read only property 'length' of object '[object Array]'
    immutableArray[0] = 5; // 非严格模式下静默失败,严格模式会直接报错
    

    注意:Object.freeze()是浅冻结,如果数组里嵌套了对象或子数组,内部的引用类型还是能被修改的。如果需要深冻结,你可以自己写一个递归函数来处理嵌套结构。

  • 操作时返回新数组(避免修改原数组)
    日常开发中,优先使用那些不修改原数组、返回新数组的方法,就能实现不可变操作:

    • 替代splice:用slice或filter
      const originalArray = [0, 2, 1, 1, 1];
      // 移除前3个元素,得到新数组
      const newArray = originalArray.slice(3);
      console.log(originalArray); // [0, 2, 1, 1, 1] 原数组完全不变
      console.log(newArray); // [1, 1]
      
    • 添加元素:用扩展运算符或concat
      const original = [1,2];
      const newArr = [...original, 3]; // 得到新数组 [1,2,3]
      // 也可以用 const newArr = original.concat(3);
      
    • 修改元素:用map
      const original = [1,2,3];
      const newArr = original.map(item => item === 2 ? 5 : item);
      // newArr是[1,5,3],原数组保持原样
      

这样就能在原生JS里实现真正的数组不可变操作啦!

内容的提问来源于stack exchange,提问作者Emeeus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:44:56