javascript中的闭包范围

时间:2011-03-23 10:38:37

标签: javascript closures

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中关闭的工作级别。

3 个答案:

答案 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()函数中就不可见了。