Il previously accepted answer non era corretto. Puoi usare bind, chiamare e applicare con i costruttori per creare nuovi costruttori, l'unico problema nel tuo test è che hai dimenticato che bind.apply e bind.call stanno applicando e chiamando bind, non il costruttore stesso , quindi hai dato gli argomenti sbagliati.
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)
Tutti e tre sono instanceof
Data.
Gli argomenti della chiamata sono il contesto di esecuzione seguito dagli argomenti da applicare. Gli argomenti di Apply sono il contesto di esecuzione e un array di argomenti. Gli argomenti di bind sono il contesto di esecuzione seguito dagli argomenti da associare.
Così gli argomenti da applicare, per esempio, sono il contesto per cui applicarelegano (Data), seguita da una matrice che è gli argomenti per bind (in modo che il primo membro array è contestuale del bind discussione). Questo è il motivo per cui è complicato chiamare o applicare il binding; è strano fornire argomenti di contesto a entrambi.
Si noti che, quando si utilizza il bind con i costruttori, l'argomento di contesto viene sempre ignorato perché "nuovo" crea esplicitamente un nuovo contesto. Io uso null quando l'argomento di contesto è irrilevante per mantenerlo chiaro, ma può essere qualsiasi cosa.
Nel frattempo, applicare e chiamare in questi esempi è necessario sapere che il contesto in cui devono essere applicati/chiamare bind è la funzione Date. Ho spostato "Data" su "Funzione", ove possibile, per aiutare a illuminare ciò che effettivamente fornisce il contesto in cui. Quando chiamiamo apply o call su Date.bind, stiamo davvero chiamando apply o call sul metodo bind non collegato all'oggetto Date. Il metodo di binding in questo caso potrebbe provenire da qualsiasi funzione. Potrebbe essere Number.bind.call (Date, null, 2000, 0, 1) e il risultato sarebbe esattamente lo stesso.
Se non è ovvio perché, considerare la differenza tra i seguenti esempi:
context.method();
e
var noLongerAMethod = context.method;
noLongerAMethod();
Nel secondo caso, il metodo è stato separato dal suo contesto originario (.. .non è stato precedentemente associato) e si comporterà diversamente se si basasse su "questo" internamente. Quando eseguiamo il binding di una determinata funzione come proprietà, anziché eseguirla direttamente, è semplicemente un altro puntatore al metodo di bind generico su Function.prototype.
Personalmente non penso di aver mai avuto bisogno di chiamare o applicare binding, ed è difficile immaginare una situazione per cui sarebbe una buona soluzione, ma i costruttori vincolanti per creare nuovi costruttori sono qualcosa che ho trovato molto utile a volte. In ogni caso è un puzzle divertente.
Tutti falliscono in IE 8 perché non esiste 'Date.bind'. ;-) – RobG
Mi sembra che si tratti di un uso inappropriato di "bind". Dovrebbe essere usato per creare oggetti funzionali, ma le date sono oggetti Date, non funzioni e non possono essere chiamati. Inoltre, senza l'uso di bind o call o apply, il valore * this * è * Date * comunque, quindi qual è il punto? Infine, non si sta chiamando Date come costruttore ma come funzione. – RobG
Certo, le date sono oggetti Data, ma la Data stessa è una funzione, ed è la Data stessa a cui sto tentando di collegarmi. La data è una funzione, quindi la lego e ottengo una nuova funzione, che poi uso come costruttore chiamandola con 'new'. Come ho detto all'inizio della domanda, il punto effettivo è di poter chiamare un costruttore con un elenco di argomenti determinati in fase di esecuzione. –