Widziałem obiekty tworzone w ten sposób:
const obj = new Foo;
Ale myślałem, że nawiasy nie są opcjonalne podczas tworzenia obiektu:
const obj = new Foo();
Czy poprzedni sposób tworzenia obiektów jest prawidłowy i zdefiniowany w standardzie ECMAScript? Czy są jakieś różnice między pierwszym sposobem tworzenia obiektów a późniejszym? Czy jedno jest lepsze od drugiego?
javascript
new-operator
Behrang Saeedzadeh
źródło
źródło
new a.b()
różni się odnew a().b()
, na tym, że w pierwszym przypadku,a.b
jest po raz pierwszy dostępne, przy czym w tym ostatnim przypadku, nowaa
się utworzyć.Odpowiedzi:
Cytując Davida Flanagana 1 :
Osobiście zawsze używam nawiasu, nawet jeśli konstruktor nie przyjmuje żadnych argumentów.
Ponadto JSLint może zranić twoje uczucia, jeśli pominiesz nawias. Raportuje
Missing '()' invoking a constructor
, i wydaje się, że narzędzie nie toleruje pominięcia nawiasów.1 David Flanagan: JavaScript Przewodnik definitywny: wydanie czwarte (strona 75)
źródło
new Class
dla konstruktorów bez parametrów. Jeśli to nie oznacza „opiniotwórczego”, nie wiem, co to znaczynew Object.func()
NIE jest ono równoważne znew Object().func()
. Przez zawsze dołączanie nawiasów eliminuje się możliwość popełnienia tego błędu.(new Object).func()
. Ale należy rozważyć użycie dodatkowych nawiasów i dodatkowe znaki równości, jak w==
vs===
, zły pretekstem do nauki języka.Istnieją dwie różnice między nimi:
new Date().toString()
działa idealnie i zwraca bieżącą datęnew Date.toString()
zgłasza „ TypeError: Date.toString nie jest konstruktorem ”Zdarza się, bo
new Date()
inew Date
mają różne pierwszeństwo. Według MDN część tabeli priorytetów operatora JavaScript, którą jesteśmy zainteresowani, wygląda następująco:Z tej tabeli wynika, że:
new Foo()
ma wyższy priorytet niżnew Foo
new Foo()
ma taki sam priorytet jak.
operatornew Foo
ma o jeden poziom niższy priorytet niż.
operatornew Date().toString()
działa idealnie, ponieważ ocenia jako(new Date()).toString()
new Date.toString()
zgłasza „ TypeError: Date.toString nie jest konstruktorem ”, ponieważ.
ma wyższy priorytet niżnew Date
(i wyższy niż „wywołanie funkcji”), a wyrażenie ma wartość(new (Date.toString))()
Tę samą logikę można zastosować do
… [ … ]
operatora.new Foo
ma skojarzenie od prawej do lewej, a określenienew Foo()
„skojarzenie” nie ma zastosowania. Myślę, że w praktyce nie robi to żadnej różnicy. Aby uzyskać dodatkowe informacje, zobacz to SO pytanieWiedząc o tym wszystkim, można założyć, że
new Foo()
jest to preferowane.źródło
new Foo()
należy preferowaćnew Foo
. Najlepsza jak dotąd odpowiedź.new Object().something()
jak również(new Object()).something()
.(new Date).toString()
samej liczby znaków i bardziej jawnie niżnew Date().toString
.Nie sądzę, aby istniała jakaś różnica, kiedy używasz „nowego” operatora. Zachowaj ostrożność przy wchodzeniu w ten nawyk, ponieważ te dwie linie kodu NIE są takie same:
źródło
Jeśli nie masz argumentów do przekazania, nawiasy są opcjonalne. Pominięcie ich to tylko cukier składniowy.
źródło
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-new-operator-runtime-semantics-evaluation
Oto część specyfikacji ES6, która określa sposób działania dwóch wariantów. Wariant bez nawiasów przekazuje pustą listę argumentów.
Co ciekawe, te dwie formy mają różne znaczenia gramatyczne. Pojawia się, gdy próbujesz uzyskać dostęp do członka wyniku.
źródło
Nie ma między nimi żadnej różnicy.
źródło