Hay diferencias entre los dos:
new Date().toString()
funciona perfectamente y devuelve la fecha actual
new Date.toString()
lanza " TypeError: Date.toString no es un constructor "
Sucede porque new Date()
y new Date
tienen una precedencia diferente. Según MDN, la parte de la tabla de precedencia de operadores de JavaScript que nos interesa se ve así:
╔════════════╦═════════════════════════════╦═══════════════╦═════════════╗
║ Precedence ║ Operator type ║ Associativity ║ Operators ║
╠════════════╬═════════════════════════════╬═══════════════╬═════════════╣
║ 18 ║ Member Access ║ left-to-right ║ … . … ║
║ ║ Computed Member Access ║ left-to-right ║ … [ … ] ║
║ ║ new (with argument list) ║ n/a ║ new … ( … ) ║
╠════════════╬═════════════════════════════╬═══════════════╬═════════════╣
║ 17 ║ Function Call ║ left-to-right ║ … ( … ) ║
║ ║ new (without argument list) ║ right-to-left ║ new … ║
╚════════════╩═════════════════════════════╩═══════════════╩═════════════╝
De esta tabla se deduce que:
new Foo()
tiene mayor prioridad que new Foo
new Foo()
tiene la misma precedencia que el .
operador
new Foo
tiene un nivel de precedencia menor que el .
operador
new Date().toString()
funciona perfectamente porque se evalúa como (new Date()).toString()
new Date.toString()
arroja " TypeError: Date.toString no es un constructor " porque .
tiene mayor prioridad que new Date
(y mayor que "Llamada de función") y la expresión se evalúa como(new (Date.toString))()
La misma lógica se puede aplicar al … [ … ]
operador.
new Foo
tiene asociatividad de derecha a izquierda y para new Foo()
"asociatividad" no es aplicable. Creo que en la práctica no hace ninguna diferencia. Para información adicional vea esta pregunta SO
¿Se prefiere uno sobre el otro?
Sabiendo todo eso, se puede suponer que new Foo()
se prefiere.