Код на MDN: как работает эта специфичная для IE прокладка для setTimer?

На странице MDN для setTimer есть небольшая прокладка / уровень совместимости для setTimer, который позволит Internet Explorer принимать дополнительные аргументы в методе setTimer, которые будут переданы обратному вызову.

Я в значительной степени понимаю весь код ниже:

if (document.all && !window.setTimeout.isPolyfill) {
  var __nativeST__ = window.setTimeout;
  window.setTimeout = function (
                          vCallback, 
                          nDelay /*, 
                          argumentToPass1, 
                          argumentToPass2, etc. */
                          ) {
    var aArgs = Array.prototype.slice.call(arguments, 2);
    return __nativeST__(vCallback instanceof Function ? function () {
      vCallback.apply(null, aArgs);
    } : vCallback, nDelay);
  };
  window.setTimeout.isPolyfill = true;
}

Кроме одной строки:

var aArgs = Array.prototype.slice.call(arguments, 2);

Он ссылается на arguments, но я не вижу ссылки на это имя где-либо перед этой строкой. Его также нет в списке Зарезервированные слова, поэтому он ни в коей мере не похоже на магию. Чтобы я мог понять это, он должен каким-то образом ссылаться на аргументы переопределенной функции setTimeout, а затем использовать slice() для получения каждого аргумента после первых двух.


person oligofren    schedule 24.01.2013    source источник


Ответы (3)


Объект arguments содержит все аргументы, которые были переданы в функцию, включая те, которые не были названы в объявлении функции.

Помните, что при следующей функции

function doStuf( param1 ) { /* do something */ }

также допустимо сделать такой вызов

doStuff( 'stuff', 'morestuff', 2, 'evenmorestuff' );

В этом случае вы можете ссылаться на все параметры, используя объект arguments.


Итак, в вашем конкретном коде следующая строка

var aArgs = Array.prototype.slice.call(arguments, 2);

копирует все аргументы, переданные shim-функции, кроме первых двух. Первые два, однако, были явно названы и упоминаются как таковые (vCallback и nDelay).

person Sirko    schedule 24.01.2013

arguments действительно волшебство; это объект, очень похожий на массив, содержащий аргументы, переданные текущей функции. Этот объект имеет локальную область видимости внутри всех функций.

Поскольку это не совсем массив, шаблон Array.prototype.slice.call(arguments) обычно используется для извлечения ряда (или всех) значений аргументов в настоящий массив. В данном конкретном случае aArgs оказывается массивом, содержащим все аргументы, переданные замене setTimeout, кроме первых двух.

person Jon    schedule 24.01.2013

arguments это волшебство — это аргументы, переданные функции в виде массива.

См. аргументы на MDN: "Массив -подобный объект, соответствующий аргументам, переданным функции [...], доступным во всех функциях"

person RichieHindle    schedule 24.01.2013
comment
Итак, это не зарезервированное слово само по себе, так как вы, вероятно, можете перезаписать его, указав другой аргумент var = {}. Но в таком случае на MDN должен быть другой список, представляющий собой надмножество зарезервированных слов, в котором указаны и все эти волшебные слова :) - person oligofren; 24.01.2013
comment
@oligofren: Вы правы, беглый поиск не нашел. Если вы найдете такую ​​вещь, пожалуйста, дайте ссылку здесь! - person RichieHindle; 24.01.2013