今天看到了第四章,变量作用域,里面提到了作用域链(scope chain)。开始没有明白是什么意思。后来联想到前文中提到的环境栈——当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。想到这里,之前对于数据结构和作用域的理解感觉就豁然开朗了。在编译器检查作用环境时,首先会将最外层的作用环境(变量、函数)压入到作用域栈中,然后在向下编译。当遇到另一个作用域时,将其再压入作用域栈中,但是,内层的作用域可以访问外层作用域中的变量、函数,这是只需要先栈中向下查找所使用的变量是否在栈中即可判断。当该作用域结束后,将其弹出即可。
rule2:js没有块级作用域。{}内声明的变量在{}之外也可以访问。如果初始化变量时没有使用var关键字,该变量会自动被添加到全局环境。
chapter4 小结
第四章主要讲的变量、作用域、内存问题
javascript变量可以用来保存两种类型的值:基本类型值和引用类型值。基本类型的值源自以下5中基本数据类型:undefined、null、boolean、number和string。基本类型值和引用类型值具有以下特点:
1.基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中;
2.从一个变量向另一个变量复制基本类型的值,会创建这个值得一个副本。
3.引用类型的值是对象,保存在堆内存中;
4.包含引用类型的变量实际上包含的并不是对象本身,而是一个指向该对象的指针。
5.从一个变量想另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象。
6.确定一个值是那种基本类型可以使用typeof操作符(注意 typeof null 返回的是object),而确定一个值是那种引用类型可以使用 instanceof操作符。
所有变量都存在于一个执行环境(作用域)当中,这个执行环境决定了变量的声明周期,以及哪一部分代码可以访问其中的变量。一下是关于执行环境的一点总结:
1.每次进入一个新的执行环境,都会创建一个用于搜索变量和函数作用域链;
2.函数的局部环境不仅有权访问函数作用域中的变量,而且还有权访问其包含(父)环境,乃至全局环境;
3.全局环境只能访问在全局环境中定义的变量和函数,而不能直接访问局部环境中的任何数据;
4.全局的执行环境有助于确定应该何时释放内存。
js是一门具有自动垃圾收集机制的语言,对js的垃圾收集历程作如下的总结:
1.离开作用域的值将自动被标记为可以回收,因此将在垃圾收集期间被删除;
2.“标记清除”是目前主流的垃圾收集算法,这种算法的思想是给当前不适用的值加上标记,然后再回收其内存;
3.解除变量的引用不仅有助于小初循环引用现象,而且对垃圾收集也有好处。为了确保有效的回收内存,应该及时解除不再使用的全局对象、全局对象属性以及循环引用变量的引用。