Chapter 4 变量、作用域和内存问题
值的类型
-
基本类型
- Undefined Null Boolean Number String
- 在JavaScript中,String不是对象
-
引用类型
- 可能由多个值构成的对象
不能给基本类型值添加属性
-
检测引用类型值 instanceof
- result = variable instanceof constructor
alert(person instanceof Object); alert(person instanceof Array);
- 对正则表达式使用 typeof 会返回 "object"
执行环境和作用域
-
执行环境
- 定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。
- 全局执行环境是最外围的一个执行环境。在Web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。
- 每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其弹出,把控制权返回给之前的执行环境。
- 当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。活动对象在最开始只包含一个变量,即arguments对象(在全局环境中不存在)。作用域链的下一个变量对象来自包含(外部)环境,而再下一个对象则来自下一个包含环境。
- 标识符解析是沿着作用域链一级一级地搜索标识符的过程。搜索过程始终从作用域链的前端开始,然后逐级地向后回溯,直至找到标识符为止。
执行环境分为全局执行环境和函数执行环境。
-
延长作用域链
- try-catch语句的catch块:会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。
- with语句:会将指定的对象添加到作用域链中。
-
JavaScript没有块级作用域
- 在JS中,块中声明的变量会被添加到当前的执行环境中。
if (true) { var color = "blue"; } alert(color); // "blue"
for (var i = 0; i < 10; i++) { doSomething(i); } alert(i);
-
查询标识符:
- 当在某个环境中为了读取或写入而引用一个标识符时,必须通过搜索来确定该标识符实际代表什么。搜索过程从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符。如果在局部环境中找到了该标识符,搜索过程停止,变量就绪。如果在局部环境中没有找到该变量名,则继续沿作用域链向上搜索。搜索过程将一直追溯到全局环境的变量对象。如果在全局环境中也没有找到这个标识符,则意味着该变量尚未声明。
var color = "blue"; function getColor() { return color; } alert(getColor()); // "blue"
var color = "blue"; function getColor() { var color = "red"; return color; } alert(getColor()); // "red"
垃圾收集
- 只要在IE(8-)中涉及COM(Component Object Model,组件对象模型)对象,就会存在循环引用的问题。
- 避免循环引用,尽量不要手工断开原生JavaScript对象与DOM元素之间的连接。
- 一旦数据不再有用,最好通过将其值设置为null来释放其引用——这个做法叫做解除引用。局部变量在离开其执行环境时会自动被解除引用。