Я читаю Javascript книгу "Говоря Javascript". В примере автор моделирует функцию apply для конструктора Date.
new (Function.prototype.bind.apply(Date, [null,2011,11,24]))
Заявление очень сбивает с толку, и когда я пытаюсь выяснить, я запутался в присутствии нулевого значения, и это тоже внутри массива. Может ли кто-нибудь помочь мне, объяснив внутренности этого заявления.
Развернуть выражение поэтапно
Function.prototype.bind.apply(Date, [null,2011,11,24])
Это выражение apply
функцию bind
используя Date
как context (this
) с аргументом list [null,2011,11,24]
First Function.prototype.bind
- это просто способ доступа к методу bind
который каждая функция наследует от своего прототипа. Для его использования можно использовать любую другую функцию. Например, var bind = (function(){}).bind
var bind = Date.bind
или даже var bind = Date.bind
Затем fn.apply(ctx, [arg1,..., argN])
вызывает fn
в контексте ctx
с заданными аргументами: ctx::fn(arg1,..., argN)
(где ::
is bind operator)
Тогда fn.bind(ctx, arg1,..., argN)
примерно эквивалентно созданию новой функции с ограниченным контекстом и частично применяемыми аргументами
function(moreArg1, ..., moreArgN) {
return fn.apply(ctx, [arg1, ..., argN, moreArg1, ..., moreArgN])
}
Поэтому bind.apply(fn, [ctx, arg1,..., argN])
является "тем же", что и fn.bind(ctx, arg1,..., argN)
Сочетание обоих дает
Date.bind(null,2011,11,24)
Soooo, я ни в коем случае не специалист, но позвольте мне взломать его, но пусть начнется в конце:
Массив - это аргументы, которые передаются конструктору Date
. Вы также можете использовать метод call
, в этом случае вы не используете массив, а просто добавляете аргументы:
new (Function.prototype.bind.call(Date, null, 2011, 11, 24));
Теперь это становится более запутанным, мы получили apply
на bind
.
apply
как мы знаем, вызывает функцию, к которой она применима. В этом случае bind
. Первый аргумент - this
свойство и задает контекст для call
. В этом случае Date
. Остальные аргументы передаются методу bind
. Метод bind
вызван так:
.bind(null, 2011, 11, 24);
В this
аргументах равно нуль, и игнорируются. bind
как вы знаете, возвращает вызываемую функцию. Эта вызываемая функция - это функция, на которую вызывается bind
. В этом случае Function.prototype
. Какой прототип конструктора Function
....
Ahhh, так что теперь у нас есть конструктор с this
контекстом, установленным в Date
, и где параметры для конструктора всегда: 2011
, 11
, 24
.
new (Date.bind(null,2011,11,24));
Вы можете вызвать конструктор, используя new
ключевое слово, которое создает экземпляр Date
где год 2011, месяц - декабрь (потому что январь равен 0), а день - 24-й.