目录
0. 背景 :const真的不能改变吗?
今天面试腾讯的时候,面试管问我var ,let ,const 的不同的时候,我把自己准备的东西一股脑说了一通,然而,面试管进一步问,const是真的不能被改变吗?它什么不可以改,什么可以改?原理是什么。这一问我呆住了。原来const还有许多知识点我没有掌握好。
1. const关键字概述
来一段菜鸟教程的回答:
ES2015(ES6) 新增加了两个重要的 JavaScript 关键字: let 和 const。
let 声明的变量只在 let 命令所在的代码块内有效。
const 声明一个只读的常量,一旦声明,常量的值就不能改变
const 用于声明一个或多个常量,声明时必须进行初始化,且初始化后值不可再修改:
const 声明的常量必须初始化:
// 错误写法
const PI;
PI = 3.14159265359;
// 正确写法
const PI = 3.14159265359;
初始化后值不可再修改:
const PI = 3.141592653589793;
PI = 3.14; // 报错
PI = PI + 10; // 报错
2. const的本质
const 的本质: const 定义的变量并非常量,并非不可变,它定义了一个常量引用一个值。使用 const 定义的对象或者数组,其实是可变的。下面的代码并不会报错:
// 创建常量对象
const car = {type:"Fiat", model:"500", color:"white"};
// 修改属性:
car.color = "red";
// 添加属性
car.owner = "Johnson";
// 创建常量数组
const cars = ["Saab", "Volvo", "BMW"];
// 修改元素
cars[0] = "Toyota";
// 添加元素
cars.push("Audi");
错误的是对对象/数组重新赋值:
const car = {type:"Fiat", model:"500", color:"white"};
car = {type:"Volvo", model:"EX60", color:"red"}; // 错误
const cars = ["Saab", "Volvo", "BMW"];
cars = ["Toyota", "Volvo", "Audi"]; // 错误
3. 探究const的内部逻辑
const 声明的变量如果是基本类型,那么不允许改变,如果是引用类型,那么只要不改变引用的地址就是可以的。也就是说其实const保证的并不是变量的值不动,而是变量指向的内存地址不得改动。
例如:
const message = 'hello'
- js看到变量message后,会给message分配一个内存空间0001
- 看到等号右侧的字符串‘hello'时,会立马给它分配另一个内存空间,并把‘hello'放到这个这个内存空间里0004
- js会记录这个内存地址0004
- 把这个内存地址0004放到message这个内存里,这时message中存储的就是hello字符串的存储地址0004(即指针)
//欲修改const类型的message、会报错
message = 'word' //错误
如果运行以上代码,js会将存储‘word'字符串的地址(假如是0003)赋给message,而message又是用const定义的变量,不可以改变变量里存储的内存地址。所以修改会报错。
所以只要看const指向内容不变,那就可以了。例如:
// 创建常量对象
const car = {
type:"Fiat",
model:"500",
color:"white"
};
// 修改属性:
car.color = "red";
// 添加属性
car.owner = "Johnson";
所以保持引用不变,对象的属性进行修改,或者增加属性都对引用没有影响。但是如果对对象重新赋值,那引用地址是会被改变的。如下示例代码:
<script>
car ={
type:"Fiat",
model:"500",
color:"white"
};
console.log(car)
//让car2指向car对象的地址,
car2 = car
console.log(car2)
console.log(car === car2) //true
//接着我们来改car对象,就是对car重新赋值
car = {
type:"xxx",
model:"800",
color:"red"
}
console.log(car)
//然后我们比较之前的car引用和重新赋值的car引用是不同的
//说明car重新赋值后是会改变引用地址的,跟单纯去修改属性值,添加属性等操作完全不同。
console.log(car2 === car) //false
</script>
(有任何疑问或者文中出现错误请指正,谢谢)
希望对你们有帮助~^_^觉得有用点个赞呗~~
后续我会整理JS系列、CSS系列的文档、有兴趣可关注。