【问题标题】:is if block a separate closure in javascript是 if 在 javascript 中阻止一个单独的闭包
【发布时间】:2014-08-19 09:08:46
【问题描述】:

据我所知,在另一个函数中定义的函数说 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
}

但是在下面的例子中 y 被打印出来了。我知道“if 块”的 javascript 中没有块范围之类的东西,但声明至少应该在“if”之外不可见,我的意思是不应该将 var 限制为 if 块?

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

【问题讨论】:

  • 答案就在问题中:“JavaScript 中没有块作用域之类的东西”
  • 是否在javascript中阻止单独的闭包? - 不,它不是
  • @Cerbrus 我不确定块作用域和闭包概念之间的联系。我希望这个问题的答案也能解决这个问题。我很确定“是否在 javascript 中阻止单独的闭包?”是一个有效的问题,不需要被否决。我也很确定“是否在 javascript 中阻止单独的闭包?”不需要解释为“是否在 javascript 中阻止单独的块范围?”因为我想详细了解概念
  • @Fishy:块作用域就是这样,请参阅我的回答中的第一个 sn-p:循环有自己的作用域,在循环之外,在其中声明的变量根本不'不存在。闭包由外部无法访问的元素组成,除非通过闭包返回的内容(函数,对象......)。参考我的答案中的链接
  • 是的,谢谢,很好的答案!!!除了您提到的返回对象/函数可以访问外部范围内的变量之外,我们还不能将以下概念视为闭包。 “函数中的任何变量都可以在该函数中定义的子函数中访问,但反之则不行”

标签: javascript


【解决方案1】:

JavaScript 并不是真正的块作用域。 iffor 循环没有自己的范围。任何给定范围(即:全局范围或函数)中的所有变量声明都被提升,并且 this 在该范围内的任何位置都可见。
ECMAScript6 (Harmony) 很可能会通过使用新的 let 关键字 see the wiki 将块作用域引入 JS:

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

就术语而言,这里似乎也存在一些混淆:闭包与范围不同。
上面的 sn-p 是块范围代码的示例。变量i 在循环开始时创建,一旦循环结束就不再存在。它是 GC'ed(垃圾收集)。 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

话虽这么说:
不过,您可以通过使用闭包来模拟块范围的循环。函数是有作用域的,闭包是函数返回的函数或对象。这意味着函数的返回值可以访问整个函数的范围。 See this answer for details.
应用那里的解释,并弄清楚为什么这个循环是“伪作用域”

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...

【讨论】:

    【解决方案2】:

    不。 正如你所说 - 如果块在 JS 中没有自己的闭包 - 这意味着一切都是外部闭包的一部分(在这种情况下 - y 是 B 闭包中的局部变量)。所以它将在B的身体中完全可见

    【讨论】:

      猜你喜欢
      • 2020-05-03
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 2016-03-26
      相关资源
      最近更新 更多