用const声明的是常量,不能被修改?

920 阅读2分钟

这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战

针对var定义变量存在的缺陷,ES6中新增了const来定义常量。

const声明一个只读的常量。一旦声明,常量的值就不能改变。

const a = 123;
console.log(a);
a = 456;

下述在控制台打印的例子表明,改变常量的值会报错。

image.png

const声明的变量不得改变值,意味着const一旦声明变量,就必须立即初始化,不能留到以后来赋值。

const num;
num = 123;
console.log(num)

const的作用域与let相同:只在声明所在的块级作用域有效。

image.png

const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。

if(true) {
    console.log(c);
    const c = 123;
}

image.png

const声明的常量,也与let一样不可重复声明。

注:用const声明的对象是可以被修改的。

const obj  = {
    name: 'dd'
}
console.log(obj.name);
obj.name = 'll'
console.log(obj.name)

image.png

const声明仅仅固定了obj的值,但是值(该对象)里面的内容没有被固定。 只有当我们要改变整个obj的值的时候,const会抛出错误。

const test = {
    value: 1
}
test = {
    name: 'dl'
}
console.log(test)

image.png

const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。 如果想将对象冻结,应该使用Object.freeze方法。

const objTest = Object.freeze({})
console.log(objTest)
objTest.name = 'd'
console.log(objTest)

image.png

总结

“基本数据类型”的值,保存在内存地址中,所以const定义的“基础数据类型”不可被改变。

而“引用数据类型”指向的内存地址只是一个指针,通过指针来指向实际数据,也就是说,不可被改变的是指针,而不是数据,所以const定义的“引用数据类型的”常量可以通过属性来修改值。