I was trying to solve Task#1 from https://javascript.info/call-apply-decorators
It goes like this:
Create a decorator spy(func) that should return a wrapper that saves all calls to function in its calls property.
Every call is saved as an array of arguments.
For instance:
function work(a, b) { alert( a + b ); // 'work' is an arbitrary function or method } work = spy(work); work(1, 2); // 3 work(4, 5); // 9 for (let args of work.calls) { alert( 'call:' + args.join() ); // "call:1,2", "call:4,5" }
The solution is:
function spy(func) { function wrapper(...args) { wrapper.calls.push(args); return func.apply(this, args); } wrapper.calls = []; return wrapper; }
What I do not understand in the given solution (and in Closures in general) is how the property that was assigned to the wrapper(wrapper.calls) is now also available for “work” function.
With the line work = spy(work)
we created wrapper for the “work” function. The value of the latter now is
ƒ wrapper(...args) {
wrapper.calls.push(args);
return func.apply(this, args);
}
Ok, the value of “work” is “wrapper” function. And “wrapper” has .calls property. But how this property is also present with “work”??