javascript - Kan vi utelate parenteser når vi oppretter et objekt ved å bruke «new»-operatoren?
Jeg har sett objekter bli laget på denne måten:
const obj = new Foo;
Men jeg trodde at parentesene ikke er valgfrie når man oppretter et objekt:
const obj = new Foo();
Er den tidligere måten å lage objekter på gyldig og definert i ECMAScript-standarden? Er det noen forskjeller mellom den tidligere måten å lage objekter på og den senere? Er den ene å foretrekke fremfor den andre?
Svar #1
Siterer David Flanagan1:
Som et spesielt tilfelle, for
new-operatoren bare, forenkler JavaScript grammatiken ved å tillate at parentesene utelates dersom det ikke er noen argumenter i funksjonskallet. Her er noen eksempler som brukernew-operatoren:o = new Object; // Optional parenthesis omitted here d = new Date(); ...
Personlig bruker jeg alltid parentesene, selv når konstruktøren ikke tar noen argumenter.
I tillegg kan JSLint såre følelsene dine hvis du utelater parentesene. Det rapporterer Missing '()' invoking a constructor, og det ser ikke ut til å være et alternativ for verktøyet å tolerere utelatelse av parenteser.
1 David Flanagan: JavaScript den definitive guiden: 4. utgave (side 75)
Svar #2
Det er forskjeller mellom de to:
new Date().toString()fungerer perfekt og returnerer den nåværende datoennew Date.toString()kaster "TypeError: Date.toString er ikke en konstruktør"
Det skjer fordi new Date() og new Date har forskjellig prioritet. Ifølge MDN ser delen av JavaScript-operatørprioritetstabellen vi er interessert i slik ut:
| Prioritet | Operatørtype | Associativitet | Operatører |
|---|---|---|---|
| 18 | Medlems tilgang Beregnet medlems tilgang new (med argumentliste) | venstre-til-høyre venstre-til-høyre ikke aktuelt | … . … … [ … ] ny … ( … ) |
| 17 | Funksjonskall new (uten argumentliste) | venstre-til-høyre høyre-til-venstre | … ( … ) ny … |
Fra denne tabellen følger det at:
new Foo()har høyere presedens ennnew Foonew Foo()har samme presedens som.-operatorennew Foohar ett nivå lavere presedens enn.-operatorennew Date().toString()fungerer perfekt fordi det evalueres som(new Date()).toString()new Date.toString()kaster "TypeError: Date.toString er ikke en konstruktør" fordi.har høyere presedens ennnew Date(og høyere enn "Funksjonskall") og uttrykket evalueres som(new (Date.toString))()Den samme logikken kan brukes på
… [ … ]-operatoren.new Foohar høyre-til-venstre assosiativitet, og fornew Foo()er «assosiativitet» ikke relevant. Jeg tror i praksis gjør det ingen forskjell. For mer informasjon, se dette SO-spørsmålet
Er den ene foretrukket fremfor den andre?
Med all den kunnskapen kan det antas at new Foo() foretrekkes.
Svar #3
Jeg tror ikke det er noen forskjell når du bruker «new»-operatoren. Vær forsiktig med å få denne vanen, da disse to kodelinjene IKKE er det samme:
var someVar = myFunc; // this assigns the function myFunc to someVar
var someOtherVar = myFunc(); // this executes myFunc and assigns the returned value to someOtherVar
Svar #4
Hvis du ikke har argumenter å sende, er parentesene valgfrie. Å utelate dem er bare syntaktisk sukker.
