基本类型和引用类型
基本数据类型:Undefined、Null、Boolean、Number和String
动态属性:
引用类型的变量,我们可以为其添加属性和方法,也可以改变、删除属性和方法。
复制变量值:
基本数据类型下,会产生一个新值。
引用数据类型下,会使两个变量指向同一个对象。
传递参数:
参数都是按值传递。对于引用数据类型,传递的依然是某个对象的引用,故函数操作的依然是原来对象。
检测类型:
typeof操作符是确定一个基本数据类型(字符串、数值、布尔值,undefined)的最佳工具。如果变量的值是一个对象或null,typeof操作符会返回"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)。这一做法适用于大多数全局变量和全局对象的属性。局部变量会在它们离开执行环境时自动被解除引用