我在下面创建了一个更新私有计数器的函数,该函数只能通过此函数中的另一个嵌套函数访问.
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