我有这个代码片段,我用它来演示闭包是如何工作的。我使用console.dir函数在google chrome inspector中打印函数范围。我无法弄清楚的部分是 JSBin在JSFiddle中没有在检查器中显示Closure。在两者中测试的代码都相同。
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上执行这两项操作?还是不是这样?
答案 0 :(得分:4)
闭包是指独立(自由)变量的函数(在本地使用但在封闭范围内定义的变量)。
如果我们使用MDM中的this definition并将其应用于您的基本示例并在浏览器中运行(无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元素。
<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
变量是在封闭范围内定义的本地使用的变量,并且是一个闭包。这就是为什么当你看一下你的控制台时,你在输出中看到了一个Closure。