基本类型和引用类型的值
js里面变量包含两种不同数据类型,
- 基本类型值
- 引用类型值
上一章说到的Undefined,Null,Boolean,Number,String类型都是基本数据类型
-
如果一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到新变量分配的位置。
简单来说就是如果是基本数据类型的复制,就是单纯的把这个值复制一份,然后赋值给另外一个变量,它们直接互不关联. -
如果一个变量向另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制给一个新变量分配的空间中。不同的时,这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一个对象。复制操作结束后,两个变量实际上将引用同一个对象。因此,改变其中一个变量,就会影响另一个变量。
简单的说,就是如果复制的是引用类型,实际上是复制了一个指针,两个指针都指向相同的地方,如果修改了其中一个里面的东西,另外一个也会对应的发生变化.
函数的参数传递是按值传递的,也就是说,把函数外部的值复制给函数内部的参数,就像把值复制给另外一个值一样.基本类型传递和基本类型变量的复制是一样的,同理,引用类型传递和引用类型的复制也是一样的.
例如:
var a = 1;
function fn(a) {
a = 5
}
fn(2)
console.log(a);//1
var obj = {};
function fn2(a) {
a.name = '123'
}
fn2(obj)
console.log(obj); //{name: "123"}
注意:当在函数内部重写obj时,这个变量引用的就是一个局部对象了,这个局部对象会在函数执行完毕后立即被销毁
例如:
function fn2(a) {
a.name = '123'
a = {name:'22'}//即使把a重新定义了,结果还是没有变化
}
fn2(obj)
console.log(obj); //{name: "123"}
垃圾回收
js具有自动垃圾回收机制,简单的说就是会自动去清理不需要的垃圾,减少占用的内存.
- 标记清除法
javascript中最常用的垃圾收集方式是标记清除(mark-and-sweep)。当变量进入环境(例如,在函数中声明一个变量)时,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占的内存,因为只要执行流进入相应的环境,就可能用到它们。而当变量离开环境时,这将其标记为“离开环境”。 - 引用计数(不太常见)
引用计数的含义是跟踪记录每个值被引用的次数。当声明一个变量并将引用类型的值赋给该变量时,则这个值的引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次数加1。相反,如果包含对这个值引用的变量又取得另外一个值,则这个值的引用次数减1.当这个值的引用次数变成0时,则说明没有办法访问这个值了,因此就可以将其占用的内存空间回收回来。这样当垃圾收集器下次再运行时,它就会释放那些引用次数为零的值所占用的内存。
确保占用最少内存可以让页面获得更好的性能,最好通过将其值设置为null来释放其引用——这个做法叫做解除引用(dereferencing)。这一做法是用于大多数全局变量和全局对象的属性。局部变量会在他们执行环境时自动被解除引用,不过,解除一个值的引用并不意味着自动回收该值所占用的内存.解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其收回
有几个点
- 基本类型值在内存中占据固定大小的空间,因此被保存在栈中
- 从一个变量向另外一个变量复制基本类型的值,会创建这个值的副本
- 引用类型的值是对象,保存在堆内存中
- 引用类型的变量不是对象本身,而是一个指向该对象的指针
- 复制引用类型的变量,复制的其实是指针,因此复制后的变量和被复制的变量指针都指向同一个对象
- 确定一个基本变量类型的值可以用typeof,确定一个引用类型的值可以用instanceof
网友评论