我们在开发的过程中一定常常发现const
关键字定义的简单类型变量 不可以改变,但是你如果定义的是一个复杂类型变量(比如对象)的话对里面属性的增删改查是可以的,那这又是为什么呢?
看下文
const关键字是让什么不能变?
const
实际上的不能变 并不是说变量的值不能变,而是初始化后变量所指向在栈中的内存上的数据不能变
我们先切记这一点先,看下文!!!
js中变量的两种类型
js中的变量类型可以分为两种:
-
简单数据类型
- Number
- String
- Boolean
- Undefined
- null
- symbol
-
复杂数据类型(下面我都称为对象)
- Object
- Array
- Function(函数实际上是对象)
两种类型的的存储区别
堆 和栈都是两种数据结构,靠他们来给变量分配使用内存
而js
的两种数据类型的变量即是存储在堆和栈中
简单类型变量的存储
这种类型的变量我们是用得最多的
它是存储在栈中而已
以下是的示例定义
js
var num=100
var bool=false
var str='字符串
而他在栈中的存储可以形象比喻为这样子
其中变量的值 存储在变量指向的栈中的内存地址上,看上图,100
就是存储在内存地址上
结合上面所说的const的作用就知道为什么const关键字定义的简单类型的变量的值不能变,因为改变其变量的值是直接改变变量指向的内存上的数据,这是const关键字不允许的
那为什么复杂类型的又可以呢,看下文
复杂类型变量的存储
先说一下,复杂类型的值的更改指的是
复杂类型变量里属性可以更改,整个对象的更改const关键字是不允许的!!!
比如
js
const ob={
a:100,
b:200
}
const ob1={
c:100
}
ob.a=200 // successful ! ! !
ob=ob1 // fail ! ! !
如果需要替换整个对象,const
关键字是不允许的,但是属性值的更改是可以的
那这又是为什么 ? 看下面
我们先要记住const
关键字是不允许更改变量的哪个地方,是变量在栈中存储变量值的内存地址上的值
对,没错 !!!这也是普通变量值不能更改的原因
但是为什么复杂变量的可以更改呢,但是不可以替换呢
主要原因是:
复杂变量的值不是存储在栈中,而是存储在堆里,复杂变量在栈中内存上的值是指向存储该复杂类型变量值的堆上的地址
如果这句话看不懂的话,可以看下图
所以更改对象的属性值是更改在堆上的值,而替换对象则是要更改存储在栈中内存地址上变量在堆上存储数据的地址值,而这个更改恰恰是const
关键字不允许的!!!
这也是为什么会有对象的浅拷贝和深拷贝的原因,因为你把一个对象直接赋值给另一个对象,准确来说是把对象变量在栈中的存储的指向改变了,指向了同一个在堆里存储的数据,所以你改变其中一个变量的值,会造成其堆上存储的数据改变,所以另外一个对象的值也会改变,这就是为啥会有浅拷贝!!!