There is a simple example of the logging function:

function work(a) { /* ... */ // work - произвольная функция } function makeLogging(f, log) { return function(){ log.push(arguments[0]); f.apply(this,arguments); } } var log = []; work = makeLogging(work, log); work(1); // 1, добавлено в log work(5); // 5, добавлено в log for (var i = 0; i < log.length; i++) { alert( 'Лог:' + log[i] ); // "Лог:1", затем "Лог:5" } 

With this code, everything works successfully, according to the comments. Initially, I tried it differently:

 function makeLogging(f, log) { return function(){ log=[].slice.call(arguments);// изменения тут f.apply(this,arguments); } } 

For obvious reasons, this did not work as planned by the task, but I expected from this code that the log array will always have the value of the argument of the last function called, however, if after calling work(1) look at the contents of the log , it will be empty. I do not fully understand why.

    1 answer 1

    Because a local variable is assigned a new value, there is no mapping to the global variable.

    The problem is rather in the wrong naming, if you rename it a little, it will become clearer:

     var log = []; function makeLogging(f, logArr) { return function(){ logArr=[].slice.call(arguments);// изменения тут f.apply(this,arguments); } } 

    Now it is clear that changes occur precisely with a local variable, and not a global one, the value of which is checked after the function is executed.

    To solve, it is enough to change not the entire link, but one element, or push / shift , which change the transmitted array itself.

    For example:

     function work(a) { console.log('work', a); } function makeLogging(f, log) { return function() { log[0] = [].slice.call(arguments); // изменения тут f.apply(this, arguments); } } var log = []; work = makeLogging(work, log); work(1); // 1, добавлено в log console.log(log) 

    • But after all, I am passing a link to a global object to a function, do I understand correctly that using my 2nd option, I’m overwriting my link, losing context? - Kayrosik
    • It is not very clear what is the passed-in array as an argument to the function. I thought that this is a reference to a memory area, it is static and, if I perform an assignment, the reference remains the same, only the value in the memory cells to which this reference points is changed. And so it turns out that when assigning, I seem to have created a new local variable - Kayrosik
    • @Kayrosik, do I understand correctly that using my 2nd option, I’m “rubbing” my link, losing context? - yes, after assigning a local variable starts to refer to the new array, which returned slice , if you derive it inside the function - you will see that everything is in order. - Grundy
    • one
      @Kayrosik, the link to the array is passed as an argument, then the value of the parameter is a link, if you assign a different value to the parameter - the original link does not change at all. - Grundy
    • @Grundy @Kayrosik - It is necessary log[0]=[].slice.call(arguments); remake to [].push.apply(log, [].slice.call(arguments)); and everything will be OK - Alexander Lonberg