第七章 函数表达式(3.模仿块级作用域)

  ·   JS高设(第三版)   ·   JavaScript     浏览量:

概述

js中没有块级作用域的概念。这意味着在块级语句中定义的变量,实际上是在包含在函数中而非语句中创建的。

function outputNumbers(count) {
    for (var i = 0; i < count; i++) {
        console.log(i); // 0~4
    }
    
    // var i;
    
    console.log(i); // 5
}

上面代码中,从i开始定义开始,就能在函数内部随处访问他,所以第二个console也能打印出内。
即使将注释放开,也依然能够输出5,因为js从来不会告诉你是否多次声明了同一个变量,他会对后续生命视而不见(不过他会执行后面生命中的变量值初始化)。

语法

匿名函数可以用来模仿块级作用域,并避免这个问题。语法如下

(function () {
    // 这里是块级作用域
})()

以上代码创建并立即调用了一个匿名函数。将函数声明包含在一对圆括号中,表示他知己上是一个函数表达式。而紧随以后的另一对圆括号会立即调用这个函数。

以下代码就会报错

function outputNumbers(count) {
    (function () {
        // 这里是块级作用域
        for (var i = 0; i < count; i++) {
            console.log(i);
        }
    })()
    console.log(i); // 这里会报错"i is not defined"
}

outputNumbers(5);

应用

这种技术经常在全局作用域中被用在外部函数,从而限制向全局作用域中添加过多的变量和函数。一般来说,我们都应该尽量减少向全局作用域中添加变量和函数。在一个由很多开发人员共同参与的大型项目中,过多的全局变量和函数很容易导致命名冲突。而通过创建私有作用域,每个开发人员即可以使用自己的变量,又不必担心搞乱全局作用域。例如:

(function () {
    var noe = new Date();
    if(now.getMonth() == 0 && now.getDate() == 1) {
        alert("Happy new year");
    }
})();

把上面这段代码放到全局作用域中,可以用来确定1月1号,弹出新年快乐的提示。其中变量now现在是匿名函数中的局部变量,为我们不必再全局作用域中创建他。

这种做法可以减少闭包占用内存的问题,因为没有指向匿名函数的引用。是要函数执行完毕,就可以立即销毁其作用域链



收起 >>
第七章 函数表达式(3.模仿块级作用域)