Existem diferenças entre os dois:
new Date().toString()
funciona perfeitamente e retorna a data atual
new Date.toString()
lança " TypeError: Date.toString não é um construtor "
Isso acontece porque new Date()
e new Date
tem precedência diferente. De acordo com o MDN, a parte da tabela de precedência do operador JavaScript em que estamos interessados se parece com:
╔════════════╦═════════════════════════════╦═══════════════╦═════════════╗
║ 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 … ║
╚════════════╩═════════════════════════════╩═══════════════╩═════════════╝
A partir desta tabela, segue-se o seguinte:
new Foo()
tem precedência mais alta que new Foo
new Foo()
tem a mesma precedência que o .
operador
new Foo
tem um nível de precedência menor que o .
operador
new Date().toString()
funciona perfeitamente porque avalia como (new Date()).toString()
new Date.toString()
lança " TypeError: Date.toString não é um construtor " porque .
tem precedência mais alta que new Date
(e mais alta que "Chamada de Função") e a expressão é avaliada como(new (Date.toString))()
A mesma lógica pode ser aplicada ao … [ … ]
operador.
new Foo
tem associatividade da direita para a esquerda e para new Foo()
"associatividade" não é aplicável. Eu acho que na prática não faz nenhuma diferença. Para obter informações adicionais, consulte esta pergunta do SO
Um prefere o outro?
Sabendo tudo isso, pode-se presumir que new Foo()
é o preferido.