1. js中没有块级作用域的概念。这表示在块语句中定义的变量,实际上实在函数中而非语句中创建的,例如:
function outputNumbers(count){
for(var i = 0 ; i < count ; i++){
alert(i);
}
alert(i);
}
在java或者c++中,循环结束后变量i就被销毁。
但在js中,变量是定义在函数的活动对象中的,从它有定义开始,就可以在函数内部随处访问它。即使再声明一次,也不会改变它的值。
function outputNumbers(count){
for(var i = 0 ; i < count ; i++){
alert(i);
}
var i;
alert(i);
}
2. js中的垃圾收集通常有两种策略:标记清除和引用计数
标记清除:当变量进入环境(例如函数中声明一个变量)时,就把这个变量标记为进入环境。垃圾收集器在运行的时候会给内存中所有变量加上标记,然后去掉环境中的变量和被环境中变量引用的变量的标记。在此之后被加上标记的将被视为要删除的变量。最后,垃圾收集器完成内存清除工作。
引用计数:不是很常见,含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型的值赋给该变量时,这个值的引用次数为1。
当这个值的引用次数变成0时,说明没有办法再访问这个值了,因此可以将其占用的内存回收,这种方式存在一些问题,例如循环引用
3. 作用域问题
看下面一段代码:
var color = "blue";
function changeColor(){
var anotherColor = "red";
function swapColors(){
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
//这里可以访问tempColor,color,anotherColor
}
//这里可以访问color和anotherColor,不能访问tempColor
swapColors();
}
//这里只能访问color
changeColor();
延长作用域链
执行环境的类型只有两种,但可以通过其他办法延长作用域链,
例如:
· try-catch语句的catch块
· with语句
看下面的代码:
function buildUrl(){
var qs = "?debug = true";
with(location){
var url = href + qs;//实际上是location.href
}
return url;
}
with语句接受了location对象。因此其变量对象中就包含了location对象的所有属性和方法,而这个变量对象被添加到了作用域链的前端。