在js中,有两种类型,一种是值引用,另一种是引用类型
值类型和引用类型的区分 | ||
概念 | 值类型指的是 原始类型 的值,也叫 基本类型 | 引用值指的是 引用类型(类) 的值 |
数据类型 | Number、String、Boolean、Underfined、Symbol(ES6新增) | object、Array、null(指向空地址)、function(特殊引用类型,五拷贝和函数赋值一说) |
存储 | 栈(stack),占内存空间固定,使用后被销毁 | 堆(heap),占内存空间不固定,使用后不一定被销毁,只有一个对象没有任何引用时, 系统的垃圾回收机制才会回收销毁 |
赋值方式 | 1.值的拷贝,创建一个新对象 2.保存与复制的是值本身 3.两份数据在内存中是完全独立的 |
1.引用的拷贝,创建一个新引用 2.保存与复制的是指向对象的一个指针 3.变量中的存储的地址赋值一份单独存储, 两个变量中修改其中一个对象,另外一个引用来访问的时候,也会访问到修改后的值。 4.使用 new() 方法构造出的对象是引用型 |
值是否可变 | 通俗讲:原变量a赋值给新变量b,改变新变量b的值,打印a变量,则a变量值未变 | 通俗讲:改变变量b,则a变量也会 |
作用域 | 函数作用域,在函数内部修改时生效,函数销毁时失效 | 函数中被修改时修改的是运行时数据区中的值,即使函数被销毁,变量的值依旧被改变。 |
比较方式 | 值 的比较 |
引用的比较 |
检测类型 | typeof 运算符 | instanceof 运算符 |
深入分析
值类型:堆里面是变量a与变量b的直接赋值和操纵,所以打印的都是他们原始的值。
引用类型:它是堆里面将a变量赋值给内存地址,将a变量赋值给了b变量时,其实是赋值给他了内存地址,所以在堆里面,当b变量的值改变时,赋给了同一个内存地址,所以a的值也会发生改变。(这也是为了计算机引擎和性能上的优化)。
值类型的代码:
//值类型
let a =100
let b = a
a = 200
console.log(b) //100
值类型的栈图:
引用类型代码:
//引用类型
let a = { age: 20 }
let b = a
b.age =21
console.log(a.age) // 21
引用类型的堆图:
对于值类型的赋值我们可以直接赋值,对于引用类型的赋值,我们则可以采用深拷贝的方式,见本人另一章节深拷贝