[TOC]
# 变量的值、作用域和内存问题
JavaScript变量松散类型的本质,决定了它只是在特定时间用于保存特定值的一个名字。由于不存在定义某个变量必须保存何种数据类型值的规则,变量的值及其数据类型可以在脚本的生命周内改变。
## 4.1 基本类型和引用类型的值
**ECMAScript中的所有参数传递的都是值,不可能通过引用传递参数。**
ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型之。**基本类型值**源自于基本数据类型,**引用类型值**则指那些可能由多个值构成的对象。
两种数据类型的值的**特点**:
* 基本类型值在内存中占据固定大小的空间,因此被保存在**栈内存**中;
* 从一个变量向另一个变量**复制***基本类型*的值,会创建这个值的一个**副本**;
* 引用类型的值是**对象**,保存在**堆内存**中;
* 包含引用类型的变量实际上包含的并不是对象本身,而是一个指向该对象的**指针**;
* 从一个变量向另一个变量复制*引用类型*的值,复制的其实是指针,因此两个变量最终都**指向同一个对象**;
确定一个值是哪个基本类型可以用`typeof`操作符,而确定一个值是哪种引用类型可以使用`instanceof`操作符,如:
~~~
alert(person instanceof Object); //变量person是Object吗?
alert(colors instanceof Array); //变量colors是Array吗?
~~~
## 4.2 执行环境及作用域
所有变量(包括基本类型和引用类型)都存在于一个**执行环境**(也成为**作用域**)当中,这个执行环境决定了变量的生命周期,以及哪一部分代码可以访问其中的变量。
某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁(全局执行环境直到应用程序退出--例如关闭网页或浏览器--时才会被销毁)。
在Web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为**window对象**的属性和方法创造的。
**执行环境总结:**
* 执行环境有**全局**执行环境(也称全局环境)和**函数**执行环境之分;
* 每次进入一个新执行环境,都会创建一个用于**搜索变量和函数**的**作用域链**;
* 函数的局部环境不仅有权访问函数作用域中的变量,而且有权访问其包含(父)环境,乃至全局环境;
* 全局环境只能访问在全局环境中定义的变量和函数,而**不能直接访问局部**环境中的任何数据;
* 变量的执行环境有助于确定应该**何时释放内存**。
**延长作用域链**
~~~
try-catch语句的catch块
with语句
~~~
这两个语句都会在**作用域链的前端**添加一个变量对象。对with语句来说,会将指定对象添加到作用域链中。对catch语句来说,会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。
**没有块作用域**
JavaScript中没有块级作用域,因此if语句中的变量声明会添加到当前的执行环境(下例为全局环境)中。
在使用for语句时尤其要牢记这一差异,例如:
~~~
for (var i=0; i <10; i++) {
doSomething(i)
}
alert(i); // 10
~~~
由for语句创建的变量i即使在for循环执行结束后,依旧会存在于循环外部的执行环境中。
## 4.3 垃圾收集
JavaScript是一门具有自动垃圾收集机制的编程语言,开发人员不必关心内存分配和回收问题。
* 离开作用域的值将呗自动标记为可以回收,因此将在垃圾收集期间被删除。
* "标记清除"是目前主流的垃圾收集算法,算法思想是给当前不使用的值加上标记,然后再回收其内存。
* "引用计数"的算法思想是跟踪记录所有值被引用的次数。(淘汰)当代码中存在循环引用现象时,会导致问题。
* 解除变量的引用不仅有助于消除循环引用现象,而且对垃圾收集也有好处。为了确保有效地回收内存,应该及时解除不再使用的全局对象、全局对象属性以及循环引用变量的引用。
- 前言
- 第一章 JavaScript简介
- 第三章 基本概念
- 3.1-3.3 语法、关键字和变量
- 3.4 数据类型
- 3.5-3.6 操作符、流控制语句(暂略)
- 3.7函数
- 第四章 变量的值、作用域与内存问题
- 第五章 引用类型
- 5.1 Object类型
- 5.2 Array类型
- 5.3 Date类型
- 5.4 基本包装类型
- 5.5 单体内置对象
- 第六章 面向对象的程序设计
- 6.1 理解对象
- 6.2 创建对象
- 6.3 继承
- 第七章 函数
- 7.1 函数概述
- 7.2 闭包
- 7.3 私有变量
- 第八章 BOM
- 8.1 window对象
- 8.2 location对象
- 8.3 navigator、screen与history对象
- 第九章 DOM
- 9.1 节点层次
- 9.2 DOM操作技术
- 9.3 DOM扩展
- 9.4 DOM2和DOM3
- 第十章 事件
- 10.1 事件流
- 10.2 事件处理程序
- 10.3 事件对象
- 10.4 事件类型
- 第十一章 JSON
- 11.1-11.2 语法与序列化选项
- 第十二章 正则表达式
- 12.1 创建正则表达式
- 12.2-12.3 模式匹配与RegExp对象
- 第十三章 Ajax
- 13.1 XMLHttpRequest对象
- 你不知道的JavaScript
- 一、作用域与闭包
- 1.1 作用域
- 1.2 词法作用域
- 1.3 函数作用域与块作用域
- 1.4 提升
- 1.5 作用域闭包
- 二、this与对象原型
- 2.1 关于this
- 2.2 全面解析this
- 2.3 对象
- 2.4 混合对象“类”
- 2.5 原型
- 2.6 行为委托
- 三、类型与语法
- 3.1 类型
- 3.2 值
- 3.3 原生函数