Ответ 1
f = Date.bind(null, 2000,0,1)
g = Function.bind.call(Date, null, 2000, 0, 1)
h = Function.bind.apply(Date, [ null, 2000, 0, 1 ])
new f() //=> Sat Jan 01 2000 00:00:00 GMT-0500 (EST)
new g() //=> Sat Jan 01 2000 00:00:00 GMT-0500 (EST)
new h() //=> Sat Jan 01 2000 00:00:00 GMT-0500 (EST)
Все три: instanceof
Дата.
Аргументы вызова - это контекст выполнения, за которым следуют применяемые аргументы. Применить аргументы - это контекст выполнения и массив аргументов. Привязка аргументов - это контекст выполнения, за которым следуют аргументы для привязки.
Таким образом, аргументы для применения, например, являются контекстом для применения bind (Date), за которым следует массив, который является аргументом для bind (поэтому первый член массива является аргументом контекста привязки). Вот почему это запутывает вызов или применение bind; странно задавать аргументы контекста для обоих.
Обратите внимание, что при использовании связывания с конструкторами аргумент контекста всегда игнорируется, потому что "новый" явно создает новый контекст. Я использую null, когда аргумент контекста не имеет значения, чтобы это было ясным, но это может быть что угодно.
Между тем, применять и вызывать в этих примерах нужно знать, что контекст, в котором они должны применяться /call bind, - это функция Date. Я переключил "Date" на "Function", где это возможно, чтобы осветить то, что на самом деле обеспечивает контекст где. Когда мы вызываем заявку или вызываем Date.bind, мы действительно вызываем apply или вызываем метод привязки, не привязанный к объекту Date. Метод связывания в таком случае может исходить из любой функции вообще. Это может быть Number.bind.call(Date, null, 2000, 0, 1), и результат будет точно таким же.
Если не понятно, почему, рассмотрите разницу между следующими примерами:
context.method();
и
var noLongerAMethod = context.method;
noLongerAMethod();
Во втором случае метод был отделен от его исходного контекста (... если он ранее не был связан) и будет вести себя по-другому, если он полагался на 'this' внутренне. Когда мы вытаскиваем привязку к любой заданной функции как свойству, а не выполняем ее напрямую, это просто другой указатель на общий метод связывания на Function.prototype.
Лично я не думаю, что мне когда-либо приходилось звонить или применять bind, и трудно представить себе ситуацию, для которой это было бы хорошим решением, но конструкторы связывания для создания новых конструкторов - это то, что я нашел очень полезно по случаю. В любом случае это забавная головоломка.