I have a problem understanding how different ways to create a function are affecting decorators. I am trying to create a decorator that will allow me to count how may times function was called:
function counter(func) {
wrapper = function(...args) {
wrapper.counter++;
let arguments = [].slice.call(args, 0)
let result = func.apply(null, arguments);
return result;
}
wrapper.counter = 0;
return wrapper;
}
function sum(x, y, z) {
return x + y + z
}
function mul(a, b, c) {
return a * b * c
}
a = counter(sum);
b = counter(mul);
console.log(`sum of 3, 6 and 8 is ${a(3, 6, 8)}`);
console.log(`mul of 1, 2 and 3 is ${b(1, 2, 3)}`);
console.log(`sum of 2, 2 and 2 is ${a(2, 2, 2)}`);
console.log(`mul of 5, 6 and 2 is ${b(5, 6, 2)}`);
console.log(`a.counter is ${a.counter}`);
console.log(`b.counter is ${b.counter}`);
This code results in following output:
sum of 3, 6 and 8 is 17
mul of 1, 2 and 3 is 6
sum of 2, 2 and 2 is 6
mul of 5, 6 and 2 is 60
a.counter is 0
b.counter is 4
As you can see, a
and b
are sharing reference the same counter, one that belongs to b, which shouldn't be happening.
However, if I change function expression wrapper = function(...args)
to function declaration function wrapper(...args)
, like this:
function counter(func) {
function wrapper(...args) {
wrapper.counter++;
let arguments = [].slice.call(args, 0)
let result = func.apply(null, arguments);
return result;
}
wrapper.counter = 0;
return wrapper;
}
function sum(x, y, z) {
return x + y + z
}
function mul(a, b, c) {
return a * b * c
}
a = counter(sum);
b = counter(mul);
console.log(`sum of 3, 6 and 8 is ${a(3, 6, 8)}`);
console.log(`mul of 1, 2 and 3 is ${b(1, 2, 3)}`);
console.log(`sum of 2, 2 and 2 is ${a(2, 2, 2)}`);
console.log(`mul of 5, 6 and 2 is ${b(5, 6, 2)}`);
console.log(`a.counter is ${a.counter}`);
console.log(`b.counter is ${b.counter}`);
Then a
and b
are having correct counters and everything works fine:
sum of 3, 6 and 8 is 17
mul of 1, 2 and 3 is 6
sum of 2, 2 and 2 is 6
mul of 5, 6 and 2 is 60
a.counter is 2
b.counter is 2
What causes changes in behavior like that?
I tried to find solution to this problem myself, but didn't found anything of help. Any help is appreciated!