J'ai vu des objets créés de cette façon:
const obj = new Foo;
Mais je pensais que les parenthèses ne sont pas facultatives lors de la création d'un objet:
const obj = new Foo();
L'ancienne façon de créer des objets est-elle valide et définie dans la norme ECMAScript? Existe-t-il des différences entre l'ancienne façon de créer des objets et la dernière? Est-ce que l'un est préféré à l'autre?
javascript
new-operator
Behrang Saeedzadeh
la source
la source
new a.b()
est différentnew a().b()
dans la mesure où, dans le premier cas, vousa.b
accédez pour la première fois, alors que dans le dernier cas, un nouveaua
est créé en premier.Réponses:
Citant David Flanagan 1 :
Personnellement, j'utilise toujours la parenthèse, même lorsque le constructeur ne prend aucun argument.
De plus, JSLint peut blesser vos sentiments si vous omettez la parenthèse. Il signale
Missing '()' invoking a constructor
, et il ne semble pas y avoir d'option pour que l'outil tolère l'omission de parenthèses.1 David Flanagan: JavaScript le guide définitif: 4e édition (page 75)
la source
new Class
pour les constructeurs sans paramètres. Si cela n'épelle pas «d'opinion», je ne sais pas ce qui fait ...new Object.func()
n'est PAS équivalent ànew Object().func()
. En incluant toujours des parenthèses, la possibilité de faire cette erreur est éliminée.(new Object).func()
. Mais je considère que l'utilisation de parenthèses supplémentaires et de signes égaux supplémentaires, comme dans==
vs===
, est une mauvaise excuse pour ne pas apprendre votre langue.Il existe des différences entre les deux:
new Date().toString()
fonctionne parfaitement et renvoie la date actuellenew Date.toString()
lance " TypeError: Date.toString n'est pas un constructeur "Cela arrive parce que
new Date()
etnew Date
ont une priorité différente. Selon MDN, la partie du tableau de priorité des opérateurs JavaScript qui nous intéresse ressemble à:Il ressort de ce tableau que:
new Foo()
a une priorité plus élevée quenew Foo
new Foo()
a la même priorité que l'.
opérateurnew Foo
a un niveau de priorité inférieur à celui de l'.
opérateurnew Date().toString()
fonctionne parfaitement car il évalue(new Date()).toString()
new Date.toString()
renvoie " TypeError: Date.toString n'est pas un constructeur " car.
a une priorité plus élevée quenew Date
(et supérieure à "Appel de fonction") et l'expression est évaluée comme(new (Date.toString))()
La même logique peut être appliquée à l'
… [ … ]
opérateur.new Foo
a une associativité de droite à gauche et pournew Foo()
"associativité" ne s'applique pas. Je pense que dans la pratique, cela ne fait aucune différence. Pour plus d'informations, voir cette question SOSachant tout cela, on peut supposer que
new Foo()
c'est préférable.la source
new Foo()
il convient de le préférernew Foo
. La meilleure réponse jusqu'à présent.new Object().something()
aussi bien(new Object()).something()
.(new Date).toString()
même nombre de caractères et plus explicite quenew Date().toString
.Je ne pense pas qu'il y ait de différence lorsque vous utilisez le "nouvel" opérateur. Faites attention à ne pas prendre cette habitude, car ces deux lignes de code ne sont PAS les mêmes:
la source
Si vous n'avez pas d'arguments à passer, les parenthèses sont facultatives. Les omettre n'est que du sucre syntaxique.
la source
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-new-operator-runtime-semantics-evaluation
Voici la partie de la spécification ES6 qui définit le fonctionnement des deux variantes. La variante sans parenthèses passe une liste d'arguments vide.
Fait intéressant, les deux formes ont des significations grammaticales différentes. Cela apparaît lorsque vous essayez d'accéder à un membre du résultat.
la source
Il n'y a aucune différence entre les deux.
la source