如果在javascript中阻止一个单独的闭包

wal*_*lop 1 javascript

据我所知,一个函数说在另一个函数中定义的A表示B也可以访问B的局部变量.

function B() {
    var x = 10;
    function A() {
        console.log(x);    //will result in 10
        var y = 5;
    }
    console.log(y);    //ReferenceError: y is not defined
}
Run Code Online (Sandbox Code Playgroud)

但是在下面的例子中,y被打印出来.我知道javascript中的块范围没有"if block"这样的东西,但是在"if"之外的一个声明至少是不可见的,我的意思是不应该限制为if block?

function B() {
    var x = 10;
    if(1) {
        console.log(x);    //will result in 10
        var y = 5;
    }
    console.log(y);    will result in 5
}
Run Code Online (Sandbox Code Playgroud)

Eli*_*gem 7

JavaScript不是真正的块范围.一个iffor循环没有自己的范围.任何给定范围内的所有变量声明(即:全局范围或函数)都会被提升,并且在该范围内的任何位置都可见.
ECMAScript6(Harmony)很可能会通过使用new let关键字向JS引入块范围,请参阅wiki:

for (let i=0;i<12;++i)
{
    console.log(i);//logs i
}
console.log(i);//reference error
Run Code Online (Sandbox Code Playgroud)

就术语而言,似乎也存在一些混淆:闭包与范围不同.
上面的代码段是块范围代码的示例.变量i在循环开始时创建,并且在循环结束后简单地停止存在.它是GC(垃圾收集).i不再是,失去生命,它依赖于和平.闭包是完全不同的:它们依赖于非GC的变量,但无法从外部代码访问.它们只能通过闭包的返回值来访问:

var someClosure = (function()
{//this function creates a scope
    var x = 123;
    return {
        getX: function()
        {
            return x;
        },
        setX: function(val)
        {
            return x = val;
        }
    };
}());
console.log(x);//reference error
console.log(someClosure.getX());//returns 123, so "x" still exists
Run Code Online (Sandbox Code Playgroud)

话虽这么说:但是
可以通过使用闭包模仿块范围的循环.函数是作用域的,闭包是函数返回的函数或对象.这意味着函数的返回值可以访问整个函数的范围.有关详情,请参阅此答案.
应用那里解释的,并找出为什么这个循环是"伪范围":

var foo = [1,2,3,4,5,6],
    largerThan3 = (function(arr)
    {
        var resultArr = [];
        for (var i=0;i<arr.length;++i)
        {
            if (arr[i] > 3)
                resultArr.push(arr[i]);
        }
        return resultArr;
    }(foo));
console.log(i);//reference error...
Run Code Online (Sandbox Code Playgroud)