Eu vi objetos sendo criados desta maneira:
const obj = new Foo;
Mas pensei que os parênteses não são opcionais ao criar um objeto:
const obj = new Foo();
A maneira anterior de criar objetos é válida e definida no padrão ECMAScript? Existem diferenças entre a maneira anterior de criar objetos e a posterior? Um prefere o outro?
javascript
new-operator
Behrang Saeedzadeh
fonte
fonte
new a.b()
é diferente denew a().b()
, em que, no primeiro caso,a.b
é primeiramente acedido, ao passo que no último caso, uma novaa
é criado pela primeira vez.Respostas:
Citando David Flanagan 1 :
Pessoalmente, eu sempre uso parênteses, mesmo quando o construtor não aceita argumentos.
Além disso, o JSLint pode prejudicar seus sentimentos se você omitir o parêntese. Ele relata
Missing '()' invoking a constructor
e não parece haver uma opção para a ferramenta tolerar a omissão de parênteses.1 David Flanagan: JavaScript, o Guia Definitivo: 4ª Edição (página 75)
fonte
new Class
para construtores sem parâmetros. Se isso não soletrar 'teimoso', eu não sei o que faz ...new Object.func()
NÃO é equivalente anew Object().func()
. Sempre incluindo parênteses, a possibilidade de cometer esse erro é eliminada.(new Object).func()
. Mas considero usar parênteses extras e sinais de igual extras, como no==
vs===
, uma desculpa ruim para não aprender o seu idioma.Existem diferenças entre os dois:
new Date().toString()
funciona perfeitamente e retorna a data atualnew Date.toString()
lança " TypeError: Date.toString não é um construtor "Isso acontece porque
new Date()
enew 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:A partir desta tabela, segue-se o seguinte:
new Foo()
tem precedência mais alta quenew Foo
new Foo()
tem a mesma precedência que o.
operadornew Foo
tem um nível de precedência menor que o.
operadornew 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 quenew 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 paranew 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 SOSabendo tudo isso, pode-se presumir que
new Foo()
é o preferido.fonte
new Foo()
deve ser preferidonew Foo
. A melhor resposta até agora.new Object().something()
e também(new Object()).something()
.(new Date).toString()
mesma contagem de caracteres e mais explícito quenew Date().toString
.Eu não acho que exista alguma diferença quando você estiver usando o operador "novo". Tenha cuidado ao entrar nesse hábito, pois essas duas linhas de código NÃO são iguais:
fonte
Se você não tiver argumentos para passar, os parênteses são opcionais. Omiti-los é apenas açúcar sintático.
fonte
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-new-operator-runtime-semantics-evaluation
Aqui está a parte da especificação ES6 que define como as duas variantes operam. A variante sem parênteses passa uma lista de argumentos vazia.
Curiosamente, as duas formas têm significados gramaticais diferentes. Isso aparece quando você tenta acessar um membro do resultado.
fonte
Não há diferença entre os dois.
fonte