Этот упрощенный код демонстрирует аналогичный вопрос:
var x = Function.call.call;
x(alert);
В этом случае, когда Function.call.call
вызывается, он не помнит контекст, из которого она возникла (т.е. Function.call
). Чтобы сохранить этот контекст, вы могли бы использовать этот
нечестивый конструкт
трюк:
Function.call.bind(Function.call)
возвращает новую функцию, причем контекст Function.call
привязан к себе, таким образом, сохраняя контекст. Вы можете сохранить это выражение в новой переменной:
var callFn = Function.call.bind(Function.call);
Теперь callFn(alert)
идентичен alert.call()
. Обратите внимание, что любые дополнительные аргументы будут передаваться как есть, поэтому callFn(alert, window)
будет вызывать alert.call(window)
. Понимание этого поведения важно в ситуациях, когда callFn
вызывается как часть обратного вызова, такого как Array.forEach
, в результате чего три аргумента передаются на каждой итерации.
fns.forEach(callFn);
В вашем случае, ни одна из функций внутри fns
не используют аргументы, которые передаются, но за кулисами они называются так:
fns[0].call(0, fns)
Так this
равен индексу элемента (т.е. Number(0)
) и arguments[0]
равен массиву функций. Острый наблюдатель, возможно, заметил, что значение элемента падает между трещинами, хотя на него все еще можно ссылаться, используя arguments[0][this]
или, альтернативно, arguments.callee
(устаревший).
Бинго, вот и все! Большое спасибо. – georg
Хорошее продолжение обсуждения аргументов, но почему «вызывающе»? Что не так просто с аргументами [0] [this] '? – georg
@ thg435 Это хороший момент; что будет работать в этом случае :) обновлено, спасибо! –