基本类型和引用类型的值
基本类型(简单的数据段)
基本数据类型是按值访问的,因为保存在变量中的是实际的值。
引用类型(可能由多个值构成的对象)
引用类型是保存在内存中的对象,JavaScript不允许直接访问内存中的位置。所以实际上是在操作对象的引用而不是实际的对象。
1.动态的属性
只能给引用类型值动态的添加属性。
2.复制变量值
因为基本类型和引用类型的访问方式不同,在复制变量的时候也会不同。
当从一个变量向另一个变量赋值基本类型的值的时候,会创建新值,然后把值复制到此位置。
当从一个变量向另一个变量赋值引用类型的值的时候,创建的新值是一个指向对象的指针,复制的实际上是指针,所以两个值实际上将引用同一个对象。
3.传递参数
ECMAScript中所有函数的参数都是按值传递的。
在向参数传递基本类型的值时,被传递的值会复制给命名参数的局部变量,因此两者互不相关,只是拥有相同的值。
在向参数传递引用类型的值时,会把这个值在内存中的地址复制给命名参数的局部变量,因此局部变量的变化会反应在函数外部,但不代表它是按引用访问的。
证明如下:
function setName(obj) { obj.name = ‘Eric‘; obj = new Object(); obj.name = ‘Cherry‘; } var person = new Object(); setName(person); alert(person.name); //‘Eric‘
4.检测类型
typeof
variable instanceof constructor(如果变量是给定引用类型的实例,则返回true)
注:因为所有的引用类型都是Object实例,所以检测引用类型值和Object构造函数时都会返回true,如果用来检测基本数据类型,始终返回false。
执行环境及作用域
每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在环境执行完成之后,栈将其环境弹出,把控制权交给之前的执行环境。
当代码在一个环境中执行时,会创建变量对象的一个作用域链,保证对执行环境有权访问的所有变量和函数的有序访问。
1.延长作用域链
当执行流进入到斜面任何一个语句时,作用域链就会得到加长。
try-catch语句的catch块; (创建一个新的变量对象,其中包含的是被抛出的错误对象的声明)
with语句。 (会将指定的对象添加到作用域链中)
2.没有块级作用域
条件语句中定义的变量会添加到当前执行环境,而不仅在条件语句内。
声明变量:使用var声明的变量会添加到最接近的环境中。没有var声明的变量会被添加到全局环境中。
查询标识符:搜索过程始终从作用域链的最前端开始逐级向后回溯,直至找到标识符为止。
垃圾收集
1.标记清除
给存储在内存中的所有变量加上标记,定时清理。
2.引用计数
跟踪每个值被引用的次数,引用次数变为0的变量就会有垃圾收集器清理。(但是由于循环引用会导致引用次数永远不会清零,即永远不会回收。)
3.性能问题
动态分配触发垃圾回收器的变量分配、字面量、数组元素的临界值。
4.管理内存
局部变量在离开它们的执行环境的时候会自动被接触引用。
而全局变量则不会,最好的方式是数据一旦不再用,手动设置其值为null来释放其引用。
原文地址:https://www.cnblogs.com/FunkyEric/p/9050851.html