关闭javascript有助于理解示例

时间:2013-10-11 11:50:32

标签: javascript

    var Counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  };   
})();

alert(Counter.value()); /* Alerts 0 */
Counter.increment();
Counter.increment();
alert(Counter.value()); /* Alerts 2 */
Counter.decrement();
alert(Counter.value()); /* Alerts 1 */
你可以逐行解释这个代码吗?我明白了;;方法有一个可变计数器共享变量的评估,但它似乎是魔术无论如何因为我们说它在开始时为零

3 个答案:

答案 0 :(得分:2)

Javascript完全是关于范围。该代码在名为Counter的变量中定义了一个对象,但没有直接定义。它定义并调用一个返回对象的函数(使用方法increment()decrement()value())。该对象的范围是它创建的位置,因此它首先是匿名函数体,然后是全局命名空间。虽然闭包没有声明(存储)并且只调用一次,但范围仍然存在。这样对象就可以访问变量privateCounter和方法changeBy()。它是唯一可以访问这些成员的对象,因此它们被称为“私有”。

答案 1 :(得分:1)

var Counter = (function() {

这是名为Counter的对象的创建。它是通过匿名自调用函数创建的。但由于该函数是自调用的,因此不建议使用大写名称。

  var privateCounter = 0;

正在设置“私有”变量privateCounter。从某种意义上说,它是私有的,你不能直接从外面访问它。它是在匿名函数的范围内创建的,它赋予它与包含函数 - Counter的单独范围。这就是你无法从外部访问它的原因,例如Counter.privateCounter === undefined。注意:每当您尝试从匿名函数访问this时,结果将是window对象,但您无法使用window.privateCounter访问它。

  function changeBy(val) {
    privateCounter += val;
  }

这是一种“私人”方法,Counter.changeBy() === undefined。这与做var changeBy = function(val){}相同。如果你想使属性或方法“公开”(可从外部访问),你必须像这样定义它们:

this.publicCounter = 0;
this.changeBy = function(val)...

这是通常的方法,当您的对象不是通过匿名函数创建时(请查看this上面的注释),但在这种情况下,您可以像这样创建它们:

  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  };   

这些仍然是Counter的“公共”方法,它们是Counter对象范围的一部分。您可以像在警报中一样访问它们。

})();

这意味着该功能是自我调用的,例如它正在立即执行。

现在,在我开始之前......当您启动脚本时,会创建对象Counter,因为它是一个自我调用的函数。这创建了该对象的范围和它的另一个范围的匿名函数(具有一个“私有”属性和一个“私有”方法)。三个返回的方法在Counter的范围内,但是它们可以访问它的匿名函数的范围,即使该函数已经返回。这是因为这三种方法都指向该范围,它们仍然存在“一些业务”,因此垃圾收集器不会触及内部变量。返回匿名函数后,您可以访问其中的值的唯一方法是通过它返回的方法(如果有的话)。希望这很清楚。现在,让我们继续前进。

alert(Counter.value()); /* Alerts 0 */

这会调用value()对象的Counter方法。此方法进入已返回的匿名函数的范围,并返回局部变量的值。

Counter.increment();
Counter.increment();

再次调用对象的“公共”方法,该方法可以访问已返回的函数中的本地函数。

alert(Counter.value()); /* Alerts 2 */
和以前一样。但请注意privateCounter在已返回的函数范围内。你不是在创建一个新的,只是通过一些具有专有权仍然可以看到它的方法访问旧的。

Counter.decrement();
alert(Counter.value()); /* Alerts 1 */

和以前一样。

基本上,就像调用一个勤杂工(对象)一样,勤杂工总是带着他的技能(“公共”方法和属性)和工具(“私人”方法和属性)。如果你需要完成某件事,请打电话给勤杂工并告诉他该做什么,使用哪种技能,但没有他就不能使用他的工具。他拥有自己的工具集,每次打电话给他都不会购买新套装。他的钳子和你上次踩到的那些旧的钳子相同。

答案 2 :(得分:0)

它很直接,我会尽量让它更清晰,'counter'是一个对象,它包含三个函数(incrementdecrement和值)和一个变量(privateCounter) 在创建计数器时,privateCounter设置为零作为初始化,这是显而易见的,但我认为让你很难将三个函数放在一起,但想想它将它们包含在'计数器'中,现在三个函数中的每一个都返回值(value()),或者递增/递减一定数量。 现在最后6行应该有意义,第一行只复制初始值为零,然后我们递增两次,increment()函数将内部值增加两次到2,当你执行value()时它再次成为2,而decrement()也是如此。我希望我的谈话对你有用。