Javascript变量、作用域和内存问题

时间:2022-11-15 06:12:37

1. 基本类型和引用类型

Undefined、Null、Boolean、Number、String 按值访问,因为可以操作保存在变量中的实际的值。

1.1动态属性

引用类型的值可以添加属性和方法,也可以改变和删除其属性和方法。

1.2复制变量值

从一个变量向另一个变量复制基本类型的值时,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上。
从一个变量向另一个变量复制引用类型的值时,同样会将存储在变量对象的值复制一份放到为新变量分配的空间中。不过这个值的副本是一个指针,指向存储在堆中的一个对象。

1.3 传递参数

ECMAScript中所有的参数都是按值传递的。???
传递基本类型的值时:被传递的值会被复制给一个局部变量(命名参数,或者用ECMAScript的概念来说,就是arguments对象中的一个元素)
传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量

function setName(obj){
obj.name = "asd";
obj = new Object();
obj.name = "aaa"
}
var person = new Object();
setName(person);
alert(person.name); //"asd"

obj引用的是局部对象,在函数执行完毕后立即消失。

1.4 确定一个变量是哪种基本类型可以使用typeof操作符,而确定一个值是哪种引用类型可以使用instanceof操作符。

2 执行环境及作用域

执行环境(execution context):定义了变量或函数有权访问的其他数据,决定了他们各自的行为,每个执行环境都有一个与之关联的变量对象,环境定义的所有变量和函数都保存在这个对象中。
每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。
当代码在环境中执行时,会创建变量对象的一个作用域链,作用域链的用途是:保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行代码所在环境的变量对象。
如果这个环境是函数,则将其活动对象作为变量对象。活动对象最开始时只包含一个变量,即arguments对象。作用域中下一个变量对象来自包含(外部)环境。
标识符解析是沿着作用域链一级一级地搜索标识符的过程。所搜过程始终从作用域链的前段开始,然后逐级地往后回溯,知道找到标识符为止。

2.1延长作用域链

执行流进入try-catch语句的catch块
with语句

3.垃圾收集 JavaScript具有自动垃圾收集机制

3.1 标记清楚

垃圾收集器

3.2 引用计数

循环引用

3.3 性能问题

3.4 管理内存

优化内存占用最佳方式就是为执行中的代码只保存必要的数据。一旦数据不再有用,最好通过将其值设置为null来释放其引用——这个做法叫做解除引用。这一做法适合大多数全局变量和全局对象的属性,局部变量会在它们离开执行环境时自动被解除引用。
解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。
执行环境也称为作用域