js中值类型和引用类型的区别
做个笔记免得忘了,方便查看
1.ECMAScript中有五种简单数据类型(也成为基本数据类型):String,Number,Boolean,Undefined,Null。还有一种复杂数据类型:Object(本质上是由一组无序的名值对组成),但是ECMAScript2016又新增了一种基本数据类型:symbol。
2. javascript中变量类型分为值类型(基本数据类型)和引用类型
(1) 值类型:String(字符串),Number(数值),Boolean(布尔值),Undefined,Null(这5种基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值)
(2) 引用类型:Array(数组),Object(对象),Function(函数)(使用new()方法构造的对象)
3. 值类型和引用类型的区别
(1) 存储位置不同
① 值类型的变量保存在栈中,占用空间固定,当一个函数执行时,每个函数都会建立自己的内存栈,在这个函数中声明的变量将会逐个放入这块栈内存里,随着函数的执行结束,这个函数的内存栈将被销毁,那么声明的变量也会自动销毁。因此,所有在函数中声明的变量都是放在栈内存中的。(栈中存储的是基础变量以及一些对象的引用变量,基础变量的值存贮在栈中,而引用变量存储在栈中的是指向堆中的数组或对象的地址,这就是为何修改引用类型总会影响到其他指向这个地址的引用变量。)
② 引用类型的变量名会保存在栈中,但是变量值会存储在堆中,占用空间不固定,当在程序中创建一个对象时,这个对象将被保存到运行时数据区中即堆内存中,以便反复利用(因为对象的创建成本通常比较大)。堆内存中的对象不会随方法的结束而自动销毁,因为即便方法结束后,这个对象还有可能被另一个引用变量所引用(方法的参数传递时很常见),所以这个对象不会被销毁。只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它。

(2) 复制方式不同
① 值类型保存与复制的是值本身,值类型的变量直接赋值就是深复制,如

② 引用类型保存与复制的是指向对象的一个指针,引用类型的变量直接赋值实际上是传递引用,只是浅复制,值保存在内存中,而JS是不能直接访问内存的,所以对于引用类型,操作的不是实际的对象而是对象的引用。
输出结果a.money和b.money都会是300,要想实现深复制,必须在堆内存中再开辟一块空间
(3)数据类型检测不同
① 值类型使用typeof检测数据的类型;
② 引用类型使用instanceof检测数据类型;

(4)引用类型可添加属性和方法
① 值类型无法添加属性和方法,如

② 引用类型可以添加属性和方法

(5) 值之间的比较方式不同
①值类型的比较是值的比较,只有当它们的值相等的时候它们才相等。比较的时候注意”==”和”===”,双等号(==)在做比较的时候做了类型转换,而全等号(===)是值和类型相等是才能相等
两个相同字符串的比较,是值(‘{}’)的比较,完全相等
② 引用类型的比较是引用地址的比较
两个空对象在堆内存中的地址不一样,所以即使两个一模一样的对象也不一定相等,而a3和a1他们的指针是指向堆内存的同一个地址的所以输出true。
(6) 传递参数不同
①向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数,或者用ECMAScript 的概念来说,就是 arguments 对象中的一个元素)。

②向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部。

对比两图代码会发现person对象的name属性值均为"Eve",如果 person 是按引用传递的,那么 person 就会自动被修改为指向其 name 属性值为"dorola"的新对象。但是,可以看到接下来再访问 person.name 时,显示的值仍然是"Eve",所以说对象是按值传递的。
这说明即使在函数内部修改了参数的值,但原始的引用仍然保持未变。实际上,当在函数内部重写 obj 时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。
4.变量计算--强制类型转换

ok,完结!!

浙公网安备 33010602011771号