第四章 变量、作用域和内存问题

基本类型和引用类型

基本数据类型:UndefinedNullBooleanNumberString

动态属性:

引用类型的变量,我们可以为其添加属性和方法,也可以改变、删除属性和方法。

复制变量值:

基本数据类型下,会产生一个新值。

引用数据类型下,会使两个变量指向同一个对象。

传递参数:

参数都是按值传递。对于引用数据类型,传递的依然是某个对象的引用,故函数操作的依然是原来对象。

检测类型:

typeof操作符是确定一个基本数据类型(字符串、数值、布尔值,undefined)的最佳工具。如果变量的值是一个对象或nulltypeof操作符会返回"object"

instanceof操作符返回某个变量是什么类型的对象,适用于引用类型的检测。

 

执行环境及作用域

全局执行环境是window对象,故所有全局变量和函数都是window的属性和方法。

每个函数都有自己的执行环境。

注:if,while,for循环内部没有局部变量,即没有块级作用域

 

作用域链:

当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。

   

如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对象在最开始时只包含一个变量,即arguments对象(这个对象在全局环境中是不存在的)。作用域链中的下一个变量对象来自包含(外部)环境,而再下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。

arguments对象

包含的外部环境

下一个包含的外部环境

……

全局执行环境变量

   

查询标识符:

当在某个环境中为了读取或写入而引用一个标识符(变量名)时,必须通过搜索来确定该标识符实际代表什么。搜索过程从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符。如果在局部环境中找到了该标识符,搜索过程停止,变量就绪。如果在局部环境中没有找到该变量名,则继续沿作用域链向上搜索。搜索过程将一直追溯到全局环境的变量对象。如果在全局环境中也没有找到这个标识符,则意味着该变量尚未声明。

arguments对象

包含的外部环境

下一个包含的外部环境

……

全局执行环境变量

 

顶端

从上往下搜索

 

垃圾收集

JavaScript 具有自动垃圾收集机制。

标记清除:

当变量进入环境(例如,在函数中声明一个变量)时,就将这个变量标记为"进入环境"。而当变量离开环境时,则将其标记为"离开境"。

最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

引用计数:

引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次数加1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减1。当这个值的引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾收集器下次再运行时,它就会释放那些引用次数为零的值所占用的内存。

但会遇到循环引用问题,因此被放弃。

然而COM对象依然使用的是引用计数,故只要IE使用COM,就会存在循环引用问题。(COM以C++对象形式实现的)

管理内存:

确保占用最少的内存可以让页面获得更好的性能。而优化内存占用的最佳方式,就是为执行中的代码只保存必要的数据。一旦数据不再有用,最好通过将其值设置为null来释放其引用——这个做法叫做解除引用(dereferencing)。这一做法适用于大多数全局变量和全局对象的属性。局部变量会在它们离开执行环境时自动被解除引用

  

原文地址:https://www.cnblogs.com/wuchaodzxx/p/5519267.html