上一篇我们聊了 JavaScript中的数据类型之基本数据类型(Primitive Values), 本篇来聊一聊引用类型(Reference Values)
JavaScript中除了上一篇聊的基本类型(Number,String,Boolean,Null,Undefined, Symbol)之外就是引用类型了,也可以说是对象了。对象是属性和方法的集合。也就是说引用类型可以拥有属性和方法,属性又可以包含基本类型和引用类型,如Object, Array, Function等。下面来看看引用类型的一些特性。
引用类型的值是可以改变的
1 | var person = { age: 32 }; |
引用类型可以添加属性和方法
1 | var person = {}; |
引用类型的值是对象引用
1 | var a = {}; |
当从一个变量向另一个变量赋值引用类型的值时,同样也会将储存在变量中的对象的值复制一份放到为新变量分配的空间中.引用类型保存在变量中的是堆区内存地址,该地址存放的是个对象,所以,与基本数据类型的简单赋值不同,这个值的副本实际上是一个指针,而这个指针指向存储在堆内存的一个对象.那么赋值操作后,两个变量都保存了同一个对象地址,而这两个地址指向了同一个对象.因此,改变其中任何一个变量,都会互相影响, 它们的关系如下图:
因此,引用类型的赋值其实是对象保存在栈区地址指针的赋值,所以两个变量指向同一个对象,任何的操作都会互相影响。
引用类型的比较是引用的比较
1 | var a = {}; |
为什么person1和person2两个对象看起来一摸一样,但是却不相等呢?
因为引用类型的比较是引用的比较,换句话说,就是比较两个对象保存在栈区的指向堆内存的地址是否相同,此时,虽然person1和person2看起来都是一个”{}”,但是他们保存在栈区中的指向堆内存的地址却是不同的,所以两个对象不相等
引用类型是同时保存在栈区和堆区中的
引用类型的存储需要在内存的栈区(Stack)和堆区(Heap)共同完成,栈区保存变量标识符和指向堆内存的地址。 假如有以下几个对象:
1 | var person1 = {name:"change1"}; |
则这三个对象在内存中保存的情况如下图:
instanceOf
判断是否是某个对象的类型, 回头单独拿一篇来聊聊indtanceOf.
基本类型和引用类型的区别
- 基本类型变量存的是值,复杂类型的变量存的是内存地址。
- 基本类型在赋值的时候拷贝值,复杂类型在赋值的时候只拷贝地址,不拷贝值。