JavaScript中const常量值为什么不可更改?对象属性又可以更改?

为什么基础数据类型的值不可以更改?

基础数据类型的值是直接存储在 栈(stack) 中。栈是计算机内存中一个用于存储局部变量和函数调用的区域。栈中的数据存储是简单且直接的,因此 当一个基础数据类型的值被赋给变量时,变量直接存储的是数据本身的值。栈的内存分配相对简单,存取速度快。

const a = 123;
  • 栈中的数据存储:a​ 是一个基础数据类型的值(number​),所以它的值 123​ 直接存储在栈上,栈中存储的是值本身。
  • 内存地址:这个值(123​)会直接存在栈中的某个位置,const​ 的作用是 锁定 a​ 的值,即一旦被赋值为 123​,a​ 就无法再指向其他的值。

为什么引用数据类型的值是可以更改的?

引用类型的值(如对象、数组)是存储在 堆(heap) 中,栈中存储的是一个指向堆中数据的引用(内存地址)。因此,当我们修改一个引用类型的值时,实际上是在修改堆中存储的数据,而栈中的引用地址不变。当你声明一个 const​ 引用类型的变量时,const​ 锁定的是栈中的引用地址,而不是堆中的数据。对于引用类型,堆是动态分配内存的,存储内容复杂,且不如栈那样高效。

例如

const b = [1, 2, 3];
  • 内存模型:

    • 在栈中,b​ 存储的是一个指向堆中数组 [1, 2, 3]​ 的引用地址。
    • 这个地址指向的是堆中的实际数据(数组元素)。
  • 栈和堆之间的关系:

    • 栈中存储的是 b​ 的引用地址(假设是一个内存地址,例如 0x1234​)。
    • 这个地址指向堆中存储 [1, 2, 3]​ 的实际数据区域。
  • ​const​ 的作用:const​ 锁定的是 b​ 在栈中的引用地址,这意味着栈中的内存地址不能被重新赋值,b​ 不能再指向其他对象(比如重新指向一个新的数组)。但是,堆中的数据是可以修改的,因为 b​ 存储的是指向堆数据的引用。

细节补充

​const​ 并不等于不可变:对于引用类型(数组、对象等),const​ 并不意味着对象或数组本身不可变,只是锁定了栈中引用的内存地址。可以修改引用类型对象中的内容(如数组元素或对象属性),但不能让 const​ 变量引用一个新的对象或数组。

例如,下面是合法的操作:

const arr = [1, 2, 3];
arr[0] = 10;  // 合法:修改数组内容
arr.push(4);   // 合法:修改数组内容

但是,如果尝试重新赋值,就会出错:

arr = [4, 5, 6];  // 错误:不能重新赋值

你可能感兴趣的:(javascript,开发语言)