是否可以重置调用包含闭包的函数的变量?在下面的示例中,该名称为counter
。 (请注意,我不熟悉闭包,因此某些注释可能是错误的。)
function makeCounter() {
let count = 0;
return function() {
++count;
return `count equals ${count}`;
};
};
// If you just call it two times without storing the result in a variable, count is reset to zero each time
console.log(makeCounter()()); // count equals 1
console.log(makeCounter()()); // count equals 1
// Since the counter variable holds a reference to the result of the outer function's call (which is the inner returned function, which "closes over" count), the JavaScript engine won't wipe it from memory.
let counter = makeCounter();
// As expected, calling counter again updates it (storing the updated count value)
console.log(counter()); // count equals 1
console.log(counter()); // count equals 2 <-- Can you reset count as stored in counter?
答案 0 :(得分:2)
使用该代码,无法以任何方式重置count
变量,这就是闭包的力量。
您可以做的是修改计数器,并实现方法reset
function makeCounter() {
let count = 0;
const counter = function() {
++count;
return `count equals ${count}`;
}
counter.reset = () => count = 0;
return counter;
};
const counter = makeCounter();
console.log(counter());
console.log(counter());
counter.reset();
console.log(counter());
您还可以在函数中添加一个reset参数。
function makeCounter() {
let count = 0;
return function(reset) {
if (reset)
count = 0;
++count;
return `count equals ${count}`;
};
}
答案 1 :(得分:1)
考虑将参数传递给计数器函数以将其重置为0:
function makeCounter() {
let count = 0;
return function(reset) {
if (reset === true) {
count = 0;
}
++count;
return `count equals ${count}`;
};
};
console.log(counter()); // count equals 1
console.log(counter()); // count equals 2
console.log(counter(true)); // count equals 1
答案 2 :(得分:1)
目前,counter
仅能接受一条(未命名)消息,其副作用是增加内部状态count
。为了添加重置功能,您应该增加counter
以便接受更多消息。
在这方面,一种可行的方法是通过字符串参数引入显式消息传递(另请参见SICP,Chapter 3中的练习3.11):
function makeCounter() {
let count = 0;
return function (msg) {
switch (msg) {
case 'increment': count++; return count;
case 'reset': count = 0; break;
default: throw new Error('unknown message');
};
};
}
let counter = makeCounter();
console.log(counter('increment')); // output: 1
console.log(counter('increment')); // output: 2
counter('reset');
console.log(counter('increment')); // output: 1
但是,在这一点上,我们可以利用JavaScript msg
类型来机械地替换object
上的显式调度,如:
function makeCounter() {
let count = 0;
return {
increment: function() { count++; return count; },
reset: function() { count = 0; }
};
}
let counter = makeCounter();
console.log(counter.increment()); // output: 1
console.log(counter.increment()); // output: 2
counter.reset();
console.log(counter.increment()); // output: 1
因此,按照 closures are a poor man's object {1}}返回makeCounter
使得每种消息类型都与相应的闭包相关联,可以实现一种方便的解决方案。 em>参数。
答案 3 :(得分:0)
您可以将重置计数传递给以下功能
function makeCounter() {
let count = 0;
return function(startCount) {
count = startCount ? startCount : ++count;
return `count equals ${count}`;
};
};
let counter = makeCounter();
// As expected, calling counter again updates it (storing the updated count value)
console.log(counter()); // count equals 1
console.log(counter()); // count equals 2
// now counter will reset to value passed
console.log(counter(1));