JavaScript中const声明数组可修改元素值不报错的原因
为什么const声明的数组仍可修改内部元素
首先澄清最常见的认知误区:
const的常量特性,仅限制变量不能被重新赋值,不会限制变量指向的引用类型内容本身的修改。
核心原理
JavaScript中的值分为两类,存储逻辑存在本质区别:
- 原始类型(数字、字符串、布尔值、null、undefined、Symbol、BigInt):变量直接存储值本身,用
const声明后,值和变量的绑定完全锁死,任何重新赋值操作都会直接抛出TypeError。 - 引用类型(数组、对象、函数等):变量存储的只是指向堆内存实际数据位置的引用指针,
const仅保证这个指针不会被改写(也就是变量永远指向同一块内存地址),不会对这块内存里存的实际内容做任何读写限制。
你给出的复现代码如下:
const values=['a','b','c']; values[0]='aaa'; console.log(values[0]); // 输出 'aaa'
这段代码里的values[0]='aaa'操作,本质是顺着values保存的引用指针找到堆内存中的数组,修改数组内部的元素值,全程没有改动values保存的指针指向,完全符合const的约束,自然不会抛出错误。
触发const报错的场景
只有当你试图给const声明的变量重新赋值,改变它的绑定指向时,才会触发报错,比如:
const values = ['a','b','c']; // 试图让values指向一个全新的数组,直接抛出错误 values = ['x', 'y', 'z']; // Uncaught TypeError: Assignment to constant variable.
其他会改变引用指向的操作比如给数组整体重新赋值、给对象整体重新赋值都会触发同样的错误。
锁定数组内容的方法
如果需要让数组本身的元素也无法修改,可以使用Object.freeze()做浅冻结:
const values = Object.freeze(['a','b','c']); values[0] = 'aaa'; // 严格模式下抛出错误,非严格模式下修改操作静默失败 console.log(values[0]); // 仍然输出原值 'a'
注意Object.freeze()是浅冻结,如果数组中嵌套了对象、数组这类引用值,嵌套的内容仍然可以修改,需要递归执行深冻结才能完全锁定所有层级的内容。
内容的提问来源于stack exchange,提问作者Ömer Düzgün
相关产品推荐
相关产品推荐

