function f1(){
var x = 5;
this.f2 = function(){
var y = 10;
function helper(){
//Do we have x here because of closure as we have y
}
setInterval(helper,100);
}
}
我是JavaScript的初学者。我正在new f1()
创建一个对象。据我了解,helper
可以通过关闭访问y
,但我发现x
内部helper
也可以使用{{1}}。任何人都可以向我解释为什么这个以及在JavaScript中关闭的工作级别。
答案 0 :(得分:0)
您定义的每个变量都将在整个函数范围内可见。如果你想在辅助函数上看不到x,我推荐使用另一种方法:
var f1 = function () {
var x = 5; //private variable within f1 scope
}
f1.prototype.f2 = function(){
var y = 10; // private variable within f2 scope
function helper(){
// x is no longer available here
setInterval(helper,100);
}
}
答案 1 :(得分:0)
由于JavaScript函数中的作用域规则而创建了闭包。我会 说封闭的核心租户是他们之后维持国家事件 执行直到下一次执行返回到嵌套的某个代码路径 在其内部。
我认为让你绊倒的事情是这可以达到很多水平 深。或者换句话说,您不限制函数的范围 通过嵌套其中的另一个函数。
x是在f1范围内定义的变量。然后你定义 this.f2为匿名函数,其范围仍在f1内。那 意味着匿名函数可以访问x,就像它有权访问一样 年。就像帮助者可以访问y一样。这就是我向下筑巢的意思。
@masylum完美地概述了如何分隔它们:不要在其中定义x 与定义f2相同的功能。
对所有这一点的一个警告:“这个”可以改变,它不会遵循相同的 模式概述。 “this”或上下文对象是当前函数的一部分 你在。所以f1的“this”将不同于“this” 帮手。现在,对于您指定的匿名函数,它将是相同的 到f2,因为你把它分配给f1的“this”的上下文(ala this.f2 = )。
话虽这么说,你可以通过使用闭包来解决这个问题。你分配 “this”到一个新变量,然后你可以在“this”的位置使用该变量。例如:
function f3() {
this.isDone = false;
var that = this;
function helper() {
that.isDone = true;
}
setTimeout(helper, 100);
}
var obj = new f3();
obj.isDone; // Will return false.
... // Wait 100 ms and ask it again.
obj.isDone; // Should be true now.
我希望我与“这个”相切并没有太远;但是,我知道 可能是很多痛苦的根源所以如果你碰到我想要提起它 它
请允许我介绍下一个问题。请考虑以下事项。
for (var i = 0; i < 3; i++) {
setTimeout(function() {
alert(i);
}, 100);
}
如果您运行该代码,您将看到一个3次“3”的警报。实际上 不会从1到3进行计数。这是闭包的常见错误。该 原因是你在调用之前一直执行for循环 setTimeout中的回调。所以当它是匿名函数的时候 解决我的问题,每次都发现它是3个。
您可以在http://www.mennovanslooten.nl/blog/post/62和更多地了解相关信息 https://developer.mozilla.org/en/JavaScript/Guide/Closures#Creating_closures_in_loops:_A_common_mistake
答案 2 :(得分:-2)
x和y在helper()函数中都可见的原因是因为你使用var关键字使它们在f1()内的任何函数都是全局的。如果你定义了两个没有var关键字的变量,那么它们在helper()函数中就不可见了。