He visto objetos creados de esta manera:
const obj = new Foo;
Pero pensé que los paréntesis no son opcionales al crear un objeto:
const obj = new Foo();
¿Es la forma anterior de crear objetos válida y definida en el estándar ECMAScript? ¿Hay alguna diferencia entre la forma anterior de crear objetos y la posterior? ¿Se prefiere uno sobre el otro?
javascript
new-operator
Behrang Saeedzadeh
fuente
fuente
new a.b()
es diferente denew a().b()
, en que, en el primer caso,a.b
primero se accede, mientras que en el último caso,a
primero se crea un nuevo .Respuestas:
Citando a David Flanagan 1 :
Personalmente, siempre uso el paréntesis, incluso cuando el constructor no toma argumentos.
Además, JSLint puede herir tus sentimientos si omites el paréntesis. Informa
Missing '()' invoking a constructor
, y no parece haber una opción para que la herramienta tolere la omisión de paréntesis.1 David Flanagan: JavaScript, la guía definitiva: 4a edición (página 75)
fuente
new Class
para los constructores sin parámetros. Si esto no explica 'obstinado', no sé lo que hace ...new Object.func()
NO es equivalente anew Object().func()
. Al incluir siempre paréntesis, se elimina la posibilidad de cometer este error.(new Object).func()
. Pero considero que usar paréntesis y signos de igualdad adicionales, como en==
vs===
, es una mala excusa para no aprender su idioma.Hay diferencias entre los dos:
new Date().toString()
funciona perfectamente y devuelve la fecha actualnew Date.toString()
lanza " TypeError: Date.toString no es un constructor "Sucede porque
new Date()
ynew 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í:De esta tabla se deduce que:
new Foo()
tiene mayor prioridad quenew Foo
new Foo()
tiene la misma precedencia que el.
operadornew Foo
tiene un nivel de precedencia menor que el.
operadornew 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 quenew 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 paranew Foo()
"asociatividad" no es aplicable. Creo que en la práctica no hace ninguna diferencia. Para información adicional vea esta pregunta SOSabiendo todo eso, se puede suponer que
new Foo()
se prefiere.fuente
new Foo()
debería preferirsenew Foo
. La mejor respuesta hasta ahora.new Object().something()
así(new Object()).something()
.(new Date).toString()
mismo recuento de caracteres y más explícito quenew Date().toString
.No creo que haya ninguna diferencia cuando está utilizando el operador "nuevo". Tenga cuidado con este hábito, ya que estas dos líneas de código NO son lo mismo:
fuente
Si no tiene argumentos para pasar, los paréntesis son opcionales. Omitirlos es solo azúcar sintáctico.
fuente
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-new-operator-runtime-semantics-evaluation
Aquí está la parte de la especificación ES6 que define cómo funcionan las dos variantes. La variante sin paréntesis pasa una lista de argumentos vacía.
Curiosamente, las dos formas tienen significados gramaticales diferentes. Esto aparece cuando intenta acceder a un miembro del resultado.
fuente
No hay diferencia entre los dos.
fuente