我有一个用于eventlisteners的generater函数生成回调函数:
function createCallback(counter){
return function(){
counter++;
}
}
回调应该只计算点击按钮的方式。让我们生成两个函数:
var counter1 = 0;
var counter2 = 0;
var callback1 = createCallback(counter1);
var callback2 = createCallback(counter2);
将他们注册为听众:
button1.addEventListener("click", callback1);
button2.addEventListener("click", callback2);
现在我需要一个重置功能:
function reset(){
counter1 = 0;
counter2 = 0;
}
我原以为,生成器函数将对全局计数器的引用传递给生成的回调函数,回调函数将修改全局变量。但是他们没有,正如我从重置功能中学到的那样。
范围存在问题,但我不明白。
counter
函数的参数createCallback
未作为参考传递给生成的函数。修改
答案 0 :(得分:2)
您可以使用对象存储计数器并传递属性名称:
const counters = {
a: 0,
b: 0
};
function createCallback(counterName){
return function(){
counters[counterName]++;
}
}
button1.addEventListener("click", createCallback("a"));
button2.addEventListener("click", createCallback("b"));
function reset(){
counters.a = 0;
counters.b = 0;
}
(如果您不需要个人姓名,请使用带索引的数组)
另一种方法是在同一个变量上为不同的功能创建多个闭包,并将它们保存在每个计数器的一个对象中。这是OOP的方式:
function createCounter() {
var counter = 0;
return {
getCount() {
return counter;
},
reset() {
counter = 0;
},
increment() {
counter++;
}
};
}
const counter1 = createCounter();
const counter2 = createCounter();
button1.addEventListener("click", counter1.increment);
button2.addEventListener("click", counter2.increment);
function reset(){
counter1.reset();
counter2.reset();
}
(再次,如果您需要任意多次,请使用计数器数组而不是多个单独命名的变量)
答案 1 :(得分:2)
JS中的对象通过引用(实际上是通过引用值)来设置,因此这将起作用(此处使用setTimeouts
来模拟回调)
function createCallback(counter){
return function(){
counter.count++;
}
}
function reset(){
counter1.count = 0;
counter2.count = 0;
}
var counter1 = {count: 0};
var counter2 = {count: 0};
var callback1 = createCallback(counter1);
var callback2 = createCallback(counter2);
setTimeout(function(){
callback1();
document.getElementById('result').innerHTML += counter1.count + ' ';
}, 1000);
setTimeout(function(){
callback1();
document.getElementById('result').innerHTML += counter1.count + ' ';
}, 2000);
setTimeout(function(){
callback1();
document.getElementById('result').innerHTML += counter1.count + ' ';
}, 3000);
setTimeout(function(){
reset();
document.getElementById('result').innerHTML += counter1.count + ' ';
}, 4000);
<div id="result"></div>
答案 2 :(得分:1)
在Javascript中,字符串和数字等基本类型变量总是按值传递。 所以你可以使用object而不是原始vars:
将全局变量嵌入对象:
var myCounterObj = {
counter1: 0,
counter2: 0
}
以这种方式更改回调定义:
function createCallback(counter, name) {
return function() {
counter[name]++;
console.log("My counter is: " + counter[name]);
}
}
然后创建回调变量:
var callback1 = createCallback(myCounterObj, 'counter1');
var callback2 = createCallback(myCounterObj, 'counter2');
最后改变重置功能:
function reset() {
myCounterObj.counter1 = 0;
myCounterObj.counter2 = 0;
}
希望这有帮助!
答案 3 :(得分:-1)
变量counter
(counter1
,counter2
)按值传递,bot通过引用传递。为了使其工作,应将变量更改为对象:
var counter1 = {"value": 0};
var counter2 = {"value": 0};
那些可以传递给生成器函数。必须相应地改变增量:
function generate(counter){
return function(){
counter.value++;
}
}
以及重置功能:
function reset(){
counter1.value = 0;
counter2.value = 0;
}
现在可行。