Ich habe gesehen, wie Objekte auf diese Weise erstellt wurden:
const obj = new Foo;
Aber ich dachte, dass die Klammern beim Erstellen eines Objekts nicht optional sind:
const obj = new Foo();
Ist die bisherige Methode zum Erstellen von Objekten im ECMAScript-Standard gültig und definiert? Gibt es Unterschiede zwischen der früheren Art der Objekterstellung und der späteren? Wird einer dem anderen vorgezogen?
javascript
new-operator
Behrang Saeedzadeh
quelle
quelle
new a.b()
andersnew a().b()
ist, als im ersteren Falla.b
zuerst zugegriffen wird, während im letzteren Fall zuerst ein neuesa
erstellt wird.Antworten:
Zitat David Flanagan 1 :
Persönlich verwende ich immer die Klammer, auch wenn der Konstruktor keine Argumente akzeptiert.
Darüber hinaus kann JSLint Ihre Gefühle verletzen, wenn Sie die Klammern weglassen. Es wird berichtet
Missing '()' invoking a constructor
, und es scheint keine Option für das Tool zu geben, um das Auslassen von Klammern zu tolerieren.1 David Flanagan: JavaScript the Definitive Guide: 4. Ausgabe (Seite 75)
quelle
new Class
für parameterlose Konstruktoren. Wenn dies nicht "eigensinnig" bedeutet, weiß ich nicht, was ...new Object.func()
ist NICHT gleichbedeutend mitnew Object().func()
. Indem immer Klammern eingeschlossen werden, wird die Möglichkeit, diesen Fehler zu machen, ausgeschlossen.(new Object).func()
. Aber ich halte die Verwendung zusätzlicher Klammern und zusätzlicher Gleichheitszeichen wie in==
vs für===
eine schlechte Entschuldigung , wenn Sie Ihre Sprache nicht lernen.Es gibt Unterschiede zwischen den beiden:
new Date().toString()
funktioniert einwandfrei und gibt das aktuelle Datum zurücknew Date.toString()
löst " TypeError: Date.toString ist kein Konstruktor "Es passiert weil
new Date()
undnew Date
haben unterschiedliche Vorrang. Laut MDN sieht der Teil der JavaScript-Operator-Prioritätstabelle, an dem wir interessiert sind, folgendermaßen aus:Aus dieser Tabelle folgt:
new Foo()
hat eine höhere Priorität alsnew Foo
new Foo()
hat die gleiche Priorität wie der.
Operatornew Foo
hat eine Stufe niedrigere Priorität als der.
Bedienernew Date().toString()
funktioniert perfekt, weil es als bewertet(new Date()).toString()
new Date.toString()
löst " TypeError: Date.toString ist kein Konstruktor " aus, da es.
eine höhere Priorität alsnew Date
(und höher als "Funktionsaufruf") hat und der Ausdruck als ausgewertet wird(new (Date.toString))()
Die gleiche Logik kann auf den
… [ … ]
Bediener angewendet werden.new Foo
hat Assoziativität von rechts nach links und fürnew Foo()
"Assoziativität" ist nicht anwendbar. Ich denke in der Praxis macht es keinen Unterschied. Weitere Informationen finden Sie in dieser SO-FrageWenn man das alles weiß, kann man davon ausgehen, dass dies
new Foo()
bevorzugt wird.quelle
new Foo()
bevorzugt werden solltenew Foo
. Die bisher beste Antwort.new Object().something()
so gut wie zu schreiben(new Object()).something()
.(new Date).toString()
dieselbe Zeichenanzahl und expliziter als verwendennew Date().toString
.Ich glaube nicht, dass es einen Unterschied gibt, wenn Sie den "neuen" Operator verwenden. Seien Sie vorsichtig, wenn Sie sich an diese Gewohnheit gewöhnen, da diese beiden Codezeilen NICHT identisch sind:
quelle
Wenn Sie keine Argumente übergeben müssen, sind die Klammern optional. Sie wegzulassen ist nur syntaktischer Zucker.
quelle
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-new-operator-runtime-semantics-evaluation
Hier ist der Teil der ES6-Spezifikation, der definiert, wie die beiden Varianten funktionieren. Die Variante ohne Klammern übergibt eine leere Argumentliste.
Interessanterweise haben die beiden Formen unterschiedliche grammatikalische Bedeutungen. Dies wird angezeigt, wenn Sie versuchen, auf ein Mitglied des Ergebnisses zuzugreifen.
quelle
Es gibt keinen Unterschied zwischen den beiden.
quelle