El previously accepted answer era incorrecto. Puede usar bind, call y apply con constructores para crear nuevos constructores. El único problema en su prueba es que ha olvidado que bind.apply y bind.call están aplicando y llamando a bind, no al propio constructor , entonces di los argumentos equivocados.
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)
Los tres son instanceof
Fecha.
Los argumentos de la llamada son el contexto de ejecución seguido de los argumentos a aplicar. Los argumentos de Apply son el contexto de ejecución y una matriz de argumentos. Los argumentos de Bind son el contexto de ejecución seguido de los argumentos a vincular.
Así que los argumentos para aplicar, por ejemplo, son el contexto para el que se aplicabind (Fecha) seguido de una matriz que es los argumentos para se unen (por lo que la primera miembro de la matriz es el contexto de la bind argumento). Es por eso que es confuso llamar o aplicar bind; se siente extraño proporcionar argumentos de contexto a ambos.
Tenga en cuenta que, al usar bind con constructores, el argumento de contexto siempre se ignora porque 'nuevo' crea explícitamente un nuevo contexto. Utilizo null cuando el argumento de contexto es irrelevante para mantenerlo claro, pero puede ser cualquier cosa.
Mientras tanto, solicite y llame a estos ejemplos si necesita saber que el contexto en el que se aplica/llame a bind es la función Fecha. Cambié 'Fecha' a 'Función' cuando sea posible para ayudar a iluminar lo que realmente está proporcionando el contexto en el que. Cuando llamamos a apply o llamamos a Date.bind, realmente llamamos a apply o call en el método de enlace no asociado al objeto Date. El método bind en tal caso podría provenir de cualquier función. Podría ser Number.bind.call (Date, null, 2000, 0, 1) y el resultado sería exactamente el mismo.
Si no es obvio por qué, tenga en cuenta la diferencia entre los siguientes ejemplos:
context.method();
y
var noLongerAMethod = context.method;
noLongerAMethod();
En el segundo caso, el método se ha divorciado de su contexto original (.. .a menos que estuviera previamente enlazado) y se comportará de manera diferente si dependiera de 'esto' internamente. Cuando establecemos el enlace de una función como propiedad, en lugar de ejecutarlo directamente, es simplemente otro puntero al método de enlace genérico en Function.prototype.
Personalmente no creo que alguna vez haya tenido que llamar o aplicar bind, y es difícil imaginar una situación para la que sería una buena solución, pero obligar a los constructores a crear nuevos constructores es algo que he encontrado muy útil en ocasiones. En cualquier caso, es un rompecabezas divertido.
Todos fallan en IE 8 porque no hay 'Date.bind'. ;-) – RobG
Me parece que este es un uso inapropiado de 'bind'. Se debe usar para crear objetos de función, pero las fechas son objetos Date, no funciones, y no pueden invocarse. Además, sin el uso de bind o call o apply, el valor * this * es * Date * de todos modos, entonces, ¿cuál es el punto? Por último, no estás llamando a Date como un constructor, sino como una función. – RobG
Claro, las fechas son objetos de fecha, pero la fecha misma es una función, y es la fecha misma a la que intento vincularme. La fecha es una función, así que la enlace y obtengo una nueva función, que luego uso como constructor llamándola con 'new'. Como dije en la parte superior de la pregunta, el punto real es poder llamar a un constructor con una lista de argumentos determinados en tiempo de ejecución. –