2

我有这个代码片段,我用它来演示闭包是如何工作的。我使用 console.dir 函数在 google chrome 检查器中打印函数范围。我无法弄清楚的部分是JSBin 没有在检查器中显示闭包,而 JSFiddle 则显示。测试的代码在两者中都是相同的。

var outer = 2;

var addTo = function() {
  var inner = 3;
  return outer + inner;
};

console.dir(addTo);

下面是下面分享的JSBin链接。

http://jsbin.com/juhokoteho/edit?js,console

JSFiddle显示了函数范围内的闭包。我不知道为什么?这与 JS 引擎没有任何关系,因为我同时在 chrome 上执行?还是不是这样? JSFiddle 截图

JSBin 截图

4

1 回答 1

4

闭包是引用独立(自由)变量(在本地使用但在封闭范围内定义的变量)的函数。

如果我们使用MDM 中的此定义并将其应用于您的基本示例并在浏览器中运行它(没有 JSBin 或 JSFiddle)。

<html>
  <head></head>
  <body>
    <script>
      var outer = 2;

      var addTo = function() {
      var inner = 3;
      return outer + inner;
      };

      console.dir(addTo);
    </script>
  </body>
</html>

如果我们看一下控制台,您将获得以下输出:

没有关闭

没有像 JSBin 这样的闭包,这是预期的行为。我们没有在本地使用任何变量,而是在封闭范围内定义的。outer是在全局范围内定义的,而不是在封闭范围内。

现在,如果我们使用完全相同的代码,但将其插入到一个自动执行的匿名函数中:

<html>
  <head>
  </head>
  <body>
    <script>
      (function (){
        var outer = 2;

        var addTo = function() {
        var inner = 3;
        return outer + inner;
        };

        console.dir(addTo);
      })();
    </script>
  </body>
</html>

控制台输出如下:

关闭

outer不再在全局范围内定义,而是在封闭范围内,即自执行匿名函数的范围内,并且在addTo函数中本地使用。根据定义,它是一个闭包。

关于 JSBin 和 JSFiddle,出于安全原因,这两个站点都会在 iframe 中执行您的代码。在 JSBin 上,iframe 与您的代码如下所示:

<body>
  <script>
    try {var outer = 2;

    var addTo = function() {
    var inner = 3;
    return outer + inner;
    };

    window.runnerWindow.proxyConsole.dir(addTo);
    } catch (error) { throw error; }
  </script>
</body>

如果我们看一下outer,它不是在封闭范围内定义的。try这里没有定义范围,因为 JavaScript 具有函数范围但没有块范围。正如预期的那样,正如您的测试所证明的那样,控制台中没有 Closure 元素。

另一方面,JSFiddle 在他的 iframe 中使用不同的代码来执行您的代码:

<head>
  <script type="text/javascript">
    window.onload=function(){
      var outer = 2;

      var addTo = function() {
      var inner = 3;
      return outer + inner;
      };

      console.dir(addTo);
    }
  </script>
</head>

在 JSFiddle 上,您的代码被包装在一个匿名函数中,该函数将onload在窗口事件上执行。在这种情况下,您的outer变量是在封闭范围内定义的本地使用的变量,并且是一个闭包。这就是为什么当您查看控制台时,您会在输出中看到一个闭包。

于 2016-07-19T22:57:21.140 回答