【JS】 JS作用域

JS没有块级作用域,理解起来可能有点困难。先看下面这个例子:

if (true) {
    var color = 'blue'
}
console.log(color)   //'blue'

这里是在一个if语句中定义了变量color,如果是在C、C++或Java中,color会在if语句执行完毕后被销毁。但在JS中,if语句中的变量声明会将变量添加到当前的执行环境(这里是全局变量)中。再看看在for语句中:

var a = 0
for (var i = 0; i < 10; i++) {
    a += i
}
console.log(i)

1、声明变量

使用var声明的变量会自动被添加到最接近的环境中。在函数内部,最接近的环境就是函数的局部环境;在with语句中,最接近的环境是函数环境。如果初始化变量时没有使用var声明,该变量会自动被添加到全局环境。

function add (num1, num2) {
    var sum = num1 + num2
    return sum
}

var result = add(10, 20)  //30
console.log(sum)  //会报错

若省略该例子中的var关键字,sum将被添加到全局变量:

function add (num1, num2) {
    sum = num1 + num2
    return sum
}

var result = add(10, 20)  //30
console.log(sum)  //30

2、查询标识符

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

看下面两个例子:

var color = 'blue'
function getColor () {
    return color
}
console.log(getColor())  //'blue'
var color = 'blue'
function getColor () {
    var color = 'red'
    return color
}
console.log(getColor())  //'red'

总结:

1、离开作用域的值将被自动标记为可以回收,因此将在垃圾收集期间被删除。

2、“标记清除”是目前主流的垃圾收集算法,这种算法的思想是给当前不使用的值加上标记,然后再回收其内存。

3、另一种垃圾收集算法是“引用计数”,这种算法的思想是跟踪记录所有值被引用的次数。JS引擎目前都不再使用这种算法;但在IE中访问非原生JS对象时,这种算法仍然可能会存在问题。

猜你喜欢

转载自blog.csdn.net/amyleeYMY/article/details/81736485