正在更新/检索函数中的专用计数器

Updating/Retrieving private counter in function

本文关键字:专用 计数器 函数 检索 更新      更新时间:2023-09-26

我在下面创建了一个函数,它更新了一个私有计数器,该计数器只能通过该函数中的另一个嵌套函数访问。

var private = function() {
  var counter = 0;
  return {
    add: function(increment) { counter += increment},
    retrieve: function() { console.log('the counter is currently set to ' + counter)}
  }
}

这是一个句法问题。我无法通过以下方式访问功能来更新/检索计数器:

private().add(5);
private().retrieve(); // should return 5, but returns 0

然而,以相同的方式调用函数,但添加变量"p"以某种方式使其工作!

var p = private();
p.add(5);
p.retrieve(); //actually returns 5

我一辈子都想不出来。如能就此提供任何指导,我们将不胜感激。

尝试在这个网站上搜索其他问题,但在这里也找不到真正的解决方案:

访问javascript闭包中的变量

这被称为"工厂函数",它创建了一个"安全"的词法范围,这意味着函数中包含的变量不能从全局范围更改或以其他方式访问。

对工厂函数的每次调用(代码中private()的每个实例)都会再次调用工厂函数,从而创建一个新的作用域。当您分配private()的返回值时,它会将返回的对象及其对创建对象的词法范围的访问保存到该变量。

使用立即调用函数表达式语法(以下称为IIFE),我们可以展开示例来显示正在发生的事情。

第一个例子:

private().add(5);
private().retrieve();

扩展如下:

(function(){
  var counter = 0;
  return {
    add: function(increment) { counter += increment},
    retrieve: function() { console.log('the counter is currently set to ' + counter)}
  };
})().add(5);
(function(){
  var counter = 0;
  return {
    add: function(increment) { counter += increment},
    retrieve: function() { console.log('the counter is currently set to ' + counter)}
  };
})().retrieve();

而第二个例子:

var p = private();
p.add(5);
p.retrieve();

扩展如下:

var p = (function(){
  var counter = 0;
  return {
    add: function(increment) { counter += increment},
    retrieve: function() { console.log('the counter is currently set to ' + counter)}
  };
})();
p.add(5);
p.retrieve();

这就是为什么第一个例子没有提供期望的输出,而第二个例子提供了。

因此,如果您只想要一个安全作用域,并且以后不需要创建新作用域,那么IIFE就足够了。

var private = (function() {
  var counter = 0;
  return {
    add: function(increment) { counter += increment},
    retrieve: function() { console.log('the counter is currently set to ' + counter)}
  }
})();
private.add(5);
private.retrieve(); // the counter is currently set to 5
private.add(5);
private.retrieve(); // the counter is currently set to 10