这是否有资格作为Javascript闭包?

时间:2013-05-08 05:36:54

标签: javascript closures

我刚刚开始学习JS中的闭包,有人告诉我,我实际上已经编写了闭包而没有意识到它们是闭包。我认为这只是一个单例对象/类,但他认为这是一个闭包:

var myWidget = {
    counter : 0,
    init : function() {
        myWidget.left();
        myWidget.right();
    },
    left : function() {
        // whatever
    },
    right : function() {
        // whatever
    }
}
myWidget.init();

这是封闭吗?如果没有,那是什么?

4 个答案:

答案 0 :(得分:3)

是的,确实如此。

在该代码示例中,您是:

  1. 定义具有某些属性的普通对象
  2. 在其中一个属性(函数)中使用闭包来引用刚才定义的对象。
  3. 我可以看到,无论您是在全局范围内还是在另一个函数内定义var myWidget,您仍然会遍历范围链以获取对myWidget的引用。

    如果我们使用此definition of closures here

    A closure is a combination of a code block and data of 
    a context in which this code block is created.
    

    mozilla definition

    Closures are functions that refer to independent (free) variables. In other words, 
    the function defined in the closure 'remembers' the environment in which it was created.
    

    myWidget.init()内执行代码块时,您在myWidgetmyWidget.left()的调用中使用闭包来引用myWidget.right() myWidget在您的上下文/环境中的变量(而不是在init()函数中本地查找它。)

    换句话说,执行myWidget.init()时会发生以下情况:

    1. myWidget是当前function()内的局部变量吗?
    2. 向上移动到父范围(即GLOBAL)
    3. myWidget是当前(即GLOBAL)范围内的变量吗? 是 - >关闭使用
    4. 确定使用此myWidget引用来检索变量。
    5. 我从来没有想过全局范围内的闭包,但是很有意义的是,范围链继续一直行进到GLOBAL,它只是另一个function() {}代码块,它包装了所有内容并且是找到我们所追求的变量的最终来源,这是另一篇支持这种观点的文章:

      http://lostechies.com/derickbailey/2011/11/30/is-javascripts-global-scope-really-just-a-closure/

答案 1 :(得分:2)

对我来说,它看起来不像是一个封闭。这将是一个更好的例子。

function init() {
    var counter = 0;

    return {
        inc: function() {
            counter++;
        },
        show: function() {
            return counter;
        }
    }
}

此处的闭包位于counter变量附近。原因是当你说

var thing = init();

Javascript必须保留对init函数通常为本地变量的引用,因此在执行后会被销毁。通过此设置,可以返回可以操作该局部变量的函数。

尝试拨打

thing.inc();
alert(thing.show());
thing.inc();
alert(thing.show());

你会在警报中看到1然后是2,但请记住,这是你操纵的init本地变量!这是关闭。

修改

阅读了一下后,很明显有问题的代码确实有一个闭包。我最喜欢的主题是here。事实证明,我在答案中所说的是闭包的一个特例,但绝不是唯一的一个。

答案 2 :(得分:0)

在这种情况下不会创建闭包。请参阅此How do JavaScript closures work?

  

访问您的直接词法范围之外的变量会创建一个   闭合

myWidget是在全局范围内定义的,因此在访问myWidget时不会为init生成闭包。

如果在函数内部定义myWidget,并在外部函数范围内的init访问变量中定义,则会生成闭包。

var myWidget = (function() {
  var number = 1;

  return {
    counter : 0,
    init : function() {
      myWidget.left();
      myWidget.right();
      number++;
    },
    left : function() {
        // whatever
    },
    right : function() {
        // whatever
    }
  }
})();

myWidget.init();

当您使用上面的代码调用init时,会创建一个包含变量号

的闭包

答案 3 :(得分:-3)

For implementing javascript closure you have to get plugin that will take care of all closure properties like css closure and javascript closure.

and you have to implement closure like the following example 

<g:compress>
  <link rel="stylesheet" type="text/css" href="css/dp.css"/>
  <link rel="stylesheet" type="text/css" href="css/demo.css"/>    
</g:compress>
...
<div id="datepicker"></div>
<g:compress>
  <script type="text/javascript" src="common.js"/>
  <script type="text/javascript" src="closure/goog/base.js"/>
  <script>
       goog.require('goog.dom');
       goog.require('goog.date');
       goog.require('goog.ui.DatePicker');
  </script>
  <script type="text/javascript">
      var dp = new goog.ui.DatePicker();
      dp.render(document.getElementById('datepicker'));
  </script>
</g:compress>