javascript - 更新/检索函数中的私有(private)计数器

标签 javascript function object closures counter

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

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

我这辈子都弄不明白。对此的任何指导将不胜感激。

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

accessing variables in javascript closures

最佳答案

这叫做 "factory function" , 它创建了一个“安全” lexical scope ,这意味着函数中包含的变量不能被更改或以其他方式从全局范围访问。

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

使用 Immediately Invoked Function Expression语法(以下称为 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

关于javascript - 更新/检索函数中的私有(private)计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34714052/

相关文章:

javascript - 在 Javascript 中使用自定义属性数据标签隐藏 div

JavaScript 计时器不会重置

regex - 如何将 perl 正则表达式替换编写为表达式中的函数?

javascript - 定时自动更新 JSP 页面

javascript - 有没有更好的方法来处理 express 中的错误?

javascript - 更好地理解 JavaScript 参数

PHP 回显与 PHP 短回显标签

java - 为什么 java 不从用户定义的类中执行覆盖的 hashcode() 方法?

Javascript:将多维数组转换为ajax中的对象

c# - 在 .NET C# 中将动态对象转换为具体对象