我目前正在开展一个相对简单的项目并发现了一些东西:
var test = (function() {
var internal = 5;
return {
init: function() {
$(document).on('click', function() {
alert(internal);
});
}
};
}());
test.init();
我认为封闭和javascript范围(正如我所理解的)意味着一个函数只能访问它自己的变量,并且它们高于它的1级。那么为什么这样呢?当我点击文档时,我收到“5”的警报,我希望得到未定义。
这是一个JSFiddle,展示了我正在做的事情:
答案 0 :(得分:4)
我认为封闭和javascript范围(正如我所理解的)意味着一个函数只能访问它自己的变量,并且它们高于它的1级。
不,它高于所有级别。事实上,这就是全局变量在JavaScript中的作用;他们只是一个关闭行动的例子。
那么为什么这样呢?
当JavaScript引擎需要解析符号时,它首先(松散地)在符号出现的执行上下文中查找(在这种情况下,通过调用您传入的匿名函数创建的那个{{ 1}})。如果它在那里找不到匹配的变量,它会查看围绕该变量的执行上下文(在这种情况下,是通过调用on
创建的执行上下文)。如果它没有找到那里,它会查看下一个(通过调用最外面的匿名函数创建的那个)。如果没有,那么下一个级别,直到它到达全局执行上下文。
关于闭包的更多信息(在我的博客上):Closures are not complicated
请注意,我一直在说“......由对 ...的调用创建”。这是一个关键点:在程序运行时,可以(几乎总是)为给定的范围创建多个执行上下文。考虑:
init
(这只是两个级别,但它适用于你想要的多个级别。)
调用时, function foo(name) {
return function() {
alert(name);
};
}
创建并返回一个函数,该函数在调用时向我们显示创建该函数时传递给foo
的名称:
foo
调用var f1 = foo("one");
var f2 = foo("two");
f1(); // "one"
f2(); // "two"
会创建执行上下文。函数foo
创建了一个持久的引用,该引用包含该调用的变量的上下文部分(规范称它为“变量绑定对象”)。 foo
返回后,该绑定对象仍然存在,这就是为什么当我们调用函数foo
创建时,它仍然可以访问相关的foo
变量。
重要的是要记住,闭包不是得到变量的值的副本。他们得到持久引用到该变量。这就是为什么这样做的原因:
name
答案 1 :(得分:0)
Javascript是静态范围的。在编写函数时,您可以访问函数内可用的所有变量,因为它们可以从您访问它的位置获得。
var a = 10;
function foo() {
// now i have access in a
var b = 20;
// i have access to both a and b
function bar() {
// still have access to both a and b
var c = 30;
// any more nested function will have access to a,b and c
}
}