原始值与引用值
在JS中,变量可能包含两种不同数据类型的值:基本类型值(原始值)与引用类型值(引用值)。下面就从各个方面来了解一下原始值与引用值。
栈内存与堆内存
原始值与引用值是JS当中变量的两种数据类型的值,对于值来说,它的存储位置就极其重要,所以在了解原始值与引用值之前先需要了解JS中变量的存储位置。
JS中对于变量的存储主要有两种位置,栈内存和堆内存。
栈内存:
栈内存主要用于存储各种基本类型的变量,即原始值,以及对象变量的指针。
栈内存中的变量一般都是已知大小或有范围上限的,算是一种简单存储。
堆内存:
堆内存主要负责存储对象Object这种变量类型的存储。
堆内存存储的对象类型数据对于大小方面一般都是未知的。
栈内存与堆内存

原始值
概念
原始值即一些代表原始数据类型的值,也叫基本数据类型。这些基本数据类型的访问是按值进行访问的。我们不能对原始值进行属性的添加和删除。
原始值包括:
- Number
- String
- Boolean
- Null
- Undefined
存储
栈内存
复制
当一个原始变量把值赋给另一个原始变量时,只是把栈中的内容复制给另一个原始变量,所以两个变量互不影响,即在后续代码中修改了其中一个变量的值,另一个变量并不因此改变。

小栗子:

传递参数
基本类型值的传递就如同基本类型变量的复制一样。在向参数传递基本类型的值时,被传递的值就会被复制给一个局部变量。
小栗子:

比较
在对原始值进行比较时,比较的是值本身,并不是值所处的位置。
小栗子:

引用值
概念
引用类型值指的是可能由多个值构成的对象。我们可以自由的给引用对象添加或删除属性和方法。
包括:
- Object(对象)
- Function(函数)
- Array(数组)
- RegExp(正则表达式)
- Date
存储
引用值将引用变量存储在栈中,而实际的对象存储在堆内存中。每个引用变量都有一个指针指向堆内存中的实际对象。
复制
当从一个变量向另一个变量复制引用值时,实际是将存储在栈内存中的指针指向的地址进行复制,复制后的两个变量都指向堆内存中的同一个对象。

小栗子:

即:

而使用非方法改变a的值时,实际时另外在堆内存中开辟了一块内存,改变啦a的指针位置,但并不对b产生影响。
即:

传递参数
在JS中,所有的参数传递都是按值传递的。也就是将某个变量的值复制给另一个变量来完成参数的传递。
对于引用值来说,传递参数的过程就是将这个值在内存中存储的地址复制一份传给另一个参数。
引用值传参前后的两个参数指向同一个地址,所以两个参数的内容相互影响。
比较
两个引用值进行比较的时候,进行比较的时两个引用值引用变量所指向的地址,若指向的地址相同,则相等。
总结
--- | 原始值 | 引用值 |
---|---|---|
值的类型 | 基本数据类型 | 复合数据类型 |
存储位置 | 栈内存 | 堆内存 |
复制内容 | 值 | 地址 |
复制前后变量是否相互影响 | 否 | 是 |
传参 | 值的复制 | 地址的复制 |
比较 | 值(字节)的比较 | 指针指向地址的比较 |
参考资料:
博客:
书籍:
《Javascript高级程序设计第二版》