原始值和引用值
原始值
原始值即一些代表原始数据类型的值,也叫基本数据类型。
原始值包括:number,string,boolean,null,undefined这些基本数据类型都是原始值。
原始值存储在栈中。当一个原始变量把值赋给另一个原始变量时,只是把栈中的内容复制给另一个原始变量,但这两个变量互不影响,也就是说,当一个变量值改变时,另一个变量不会因此而发生任何变化。
var a = 1 ;
var b = a ;
a = 2;
console.log(b); 输出1。b的值不因a值的改变而该改变
引用值
引用值是指一些引用类型数据的值。
引用值包括:Object,function,Array,RegExp,Data,
引用值于原始值不同,引用值把引用变量存储在栈中,而实际的对象存储在堆中。每一个引用变量都有一个指针指向其堆中的实际对象。
var a = [1,2];
var b = a;
a.push(3);
console.log(a);//输出1,2,3
console.log(b);//输出1,2,3
访问时,先是通过变量名去栈内存中拿到该值在堆内存中的地址,然后通过这个地址再去堆内存访问其值。
原始值和引用值的区别
| 项 | 原始值 | 引用值 |
|---|---|---|
| 概念 | 原始值即一些代表原始数据类型的值,也叫基本数据类型 | 引用值是指一些引用类型数据的值。 |
| 数据类型 | number,string,boolean,null,undefined | Object,function,Array,RegExp,Data |
| 存储地点 | 栈内存 | 堆内存 |
| 占内存情况 | 占内存空间固定,在读取基本类型值时,后台会创建一个对应的基本包装类型的对象,以调用对应类型的方法,使用后被销毁 | 占内存空间不固定,使用后不一定被销毁,只有当一个对象没有被引用时,系统的回收机制才会将其回收销毁 |
| 值 | 不改变(一个原始变量给另一个原始变量传递值的时候,将一段栈中的内容复制到另一段栈空间中,所以两个原始变量(值)互不影响) | 改变(传递引用对象的过程实际上复制的是指向实际对象的指针,所以访问这两个变量名得到的都是实际对象的值。) |
| 比较方式 | 值的比较 | 引用的比较 |
| 检测类型 | typeof 运算符 | instanceof 运算符 |
栈内存和堆内存
栈内存
栈的数据结构
栈(stack)是限定在表尾进行插入和删除的操作的线性表。 把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不包含任何数据元素的栈称为空栈。栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。
栈内存
栈内存在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。当在一段代码块定义一个变量时,就在栈中为这个变量分配内存空间,当超过变量的作用域后,自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
堆内存
堆内存是区别于栈区、全局数据区和代码区的另一个内存区域。堆允许程序在运行时动态地申请某个大小的内存空间。
栈内存与堆内存的区别
| 项 | 栈内存 | 堆内存 |
|---|---|---|
| 特点 | 栈内存实际上就是满足先进后出的性质的数学或数据结构。栈内存是存取速度比堆要快,仅次于寄存器,栈数据可以共享。 | 堆内存实际上指的就是优先队列的一种数据结构,第1个元素有最高的优先权。 |
| 内存 | 栈内存在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。(内存小,速度快) | 堆内存是区别于栈区、全局数据区和代码区的另一个内存区域。堆允许程序在运行时动态地申请某个大小的内存空间。 |
| 对象的访问 | 可直接访问(原始值) | 不可以直接访问(访问一个对象时,先得到之歌对象在堆内存中的地址,再按照这个地址去获得·这个对象的值,即按引用访问) |
| 生命周期 | 很短 | 从程序运行开始到结束 |
| 管理方式 | LIFO | 全局被访问,管理比较复杂 |
| 优点 | 它的存取速度比较快,仅此于寄存器,栈中的数据还可以共享。 | 可动态地分配内存大小,可以“按需分配”,其生存期也不必事先告诉编译器,在使用完毕后垃圾收集器会自动收走这些不再使用的内存块。 |
| 缺点 | 存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。 | ,由于要在运动时才动态分配内存,相比于栈内存,它的存取速度较慢。 |