【问题标题】:Scope of closure in javascriptjavascript中的闭包范围
【发布时间】:2011-03-23 10:38:36
【问题描述】:
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 中使用。任何人都可以向我解释为什么会这样以及闭包在 JavaScript 中工作到什么级别。

【问题讨论】:

  • var x 是 javascript 中 f1 类的实例变量,因此它应该在 f1 的所有方法中的 f1 i-e 定义中都可用。
  • 不完全是furqan,它只对在构造函数范围内定义的函数可用。稍后添加的方法,或通过原型访问的方法,将无法访问 x。
  • 你还有一点语法错误,应该是this.f2 = function(){没有第一组()

标签: javascript closures


【解决方案1】:

您定义的每个变量都将在整个函数范围内可见。如果您希望 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);
  }
}

【讨论】:

    【解决方案2】:

    由于函数 JavaScript 中的作用域规则而创建了闭包。我会 说闭包的核心租户是他们在之后维护状态事件 执行直到下一次执行返回到某个嵌套的代码路径 在自身内部。

    我认为让你感到困惑的是,这可能会涉及多个层次 深的。或者换句话说,你不限制函数的范围 通过在其中嵌套另一个函数。

    x 是在 f1 范围内定义的变量。然后你定义 this.f2 指向一个匿名函数,其作用域仍在 f1 内。那 意味着匿名函数可以访问 x 就像它可以访问 是的。就像助手可以访问 y 一样。这就是我所说的向下嵌套的意思。

    @masylum 完美地概述了如何将它们分开:不要在 与您定义 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 中的回调。所以当匿名函数的时候 解决 i 是什么,每次都会发现它是 3。

    您可以在http://www.mennovanslooten.nl/blog/post/62https://developer.mozilla.org/en/JavaScript/Guide/Closures#Creating_closures_in_loops:_A_common_mistake

    【讨论】:

      【解决方案3】:

      x 和 y 在 helper() 函数中都可见的原因是因为您使用 var 关键字使它们对 f1() 中的任何函数都是全局的。如果您在没有 var 关键字的情况下定义了这两个变量,它们将不会在 helper() 函数中可见。

      【讨论】:

      • 如果没有 var,它们将被声明为全局(在窗口上)并且在 f1() 之外可见。
      猜你喜欢
      • 2016-03-07
      • 2019-08-20
      • 1970-01-01
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-26
      相关资源
      最近更新 更多