JavaScript 里面的数据类型分为两种
1 - 原始数据类型或者称之为基本数据类型: 听这名字就能知道这种类型不能再往下细分了。包括:
Null
Undefined
String
Number
Boolean
2 - 引用类型或者称之为对象类型, 其实称作复合类型更加适合。 包括:Object
Array
Function
Date
在声明一个变量的时候, 不同的值类型会有不同的内存分配机制。
对于一个原始值存储在栈(stack
)中,直接存在变量访问的位置。原因是原始值的存储量比较小,大小固定,这样能很方便的查找变量的值。
但是对于一个引用类型的值是存储在 堆(heap
)中的。也就是说, 存储在变量处的是一个指针,指向存储对象的内存地址。
let a = 12;
let b = a;
b
的值由 a
而来, 但是复制完成之后 a
b
就完全是两个变量了, 两者之间没有任何关系了, 任何一方的改变都不会影响另一方。
let c = { name: "spring" };
let d = c;
由前面所说对象在赋值的时候设计的值保存在堆中, c
d
都是指针, 他们都指向同一块内存区域。 let d = c
的真正含义是找到 c
的指向区域 , 将 d
这个指针指向该区域。
以后除非将 c
或者 d
的指向指向其他的区域, 否则 c
d
任何一方的对对象的改动都会影响到另外一方。
ps: 以前一直以为 ES6
的 const
赋值声明一旦对变量使用之后这个变量的值就不能再变动了, 其实不是总是这样的, 对一个原始值确实是这样, 但是对一个对象。
const e = { name: "china" };
e.name = "iron";
e.isHard = true
这样操作是完全合法的,也能得到预期的效果。 const
的真正表述应该是: 一旦你对一个变量应用了 const
, 这个变量之后就不能再指向其他的值了。对象是一个容器, 至于里面有什么属性值是什么并不关心。
举个例子: 你只能有一个身体,即使这个身体的身高变高了或者头发剪短了也是你的身体, 但是将你转移给另外一个身体就是非法的。
const e = { name: "china" };
e = { name: "iron", isHard: true }
上面这个是非法的, 虽然看起来也是有效的, 但其实这个完全不一样的, 此处是重新赋值。当然换成 var
或者 let
就合法了, 但还是重新赋值