[].slice.call(arguments) не копирует значение в массив

119
25 декабря 2019, 03:20

Имеется простой пример работы функции логирования:

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"
}

При таком коде все успешно работает, согласно комментариям. Изначально, я попробовал иначе:

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

По понятным причинам это не сработало так, как планировалось по заданию, но я ожидал от данного кода, что массив log всегда будет иметь значение аргумента последней вызванной функции, однако, если после вызова work(1) посмотреть содержимое log, он окажется пустым. Я не до конца понимаю почему.

Answer 1

Из-за того, что локальной переменной присваивается новое значение, никакого отображения на глобальной переменной нет.

Проблема скорее в неверном именовании, если немного переименовать, станет понятнее:

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

Теперь видно, что изменения происходят именно с локальной переменной, а не глобальной, значение которой проверяется после выполнения функции.

Для решения достаточно менять не всю ссылку, а один элемент, либо делать push/shift, которые меняют сам переданный массив.

Например:

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)

READ ALSO
Неизвестный оператор. (near &ldquo;WITH&rdquo; at position 0)

Неизвестный оператор. (near “WITH” at position 0)

Возникает ошибка при попытке использовать with в панели phpMyAdmin, как я понимаю phpMyAdmin использует MySQL, а в нем есть with, но вот у меня он никак его...

133
#1146 - Таблица &#39;test.tree&#39; не существует

#1146 - Таблица 'test.tree' не существует

Ошибка #1146 - Таблица 'testtree' не существует возникает в этом коде

138