Erzeugungsausdrücke in JavaScript
Die Syntax von new-Ausdrücken
Ein new-Ausdruck besteht aus dem Schlüsselwort »new«, einem Ausdruck für eine Funktion und einer optionalen Liste von Argumenten.
- new-Ausdruck (Syntaxdiagramm, vereinfacht)
new-Ausdruck (Ecma 262 2017, 12.3.3)
.-------------------------.
.---. .-------------. | .----------------. v
--->( new )--->| Ausdruck |---'--->| Argumentangabe |---'--->
'---' '-------------' '----------------'
FunktionArgumentangabe (Ecma 262 2015, 12.3)
.-. .-.
---.--->( ( )------------------------->( ) )---.--->
| '-' '-' ^
| .-. .----------------. .-. |
'--->( ( )--->| Ausdruckliste |--->( ) )---'
'-' '----------------' '-'
ArgumentlisteAusdruckliste (Ecma 262 2015, 12.3)
.----------------.
---.--->| Ausdruck |---.--->
^ '----------------' |
| Argument |
| .-. |
'----------( , )<---------'
'-'- new-Ausdruck mit Argument (Beispiel)
new f( 3 )
- new-Ausdruck mit Argumentangabe, aber ohne Argument (Beispiel)
new f()
- new-Ausdruck ohne Argumentangabe
new f
Als Ausdruck für die Funktion (direkt hinter »new«) sind – etwas vereinfacht gesagt – nur einfache Ausdrücke wie Eintragsausdrücke oder eingeklammerte Ausdrücke zugelassen. In den meisten Fällen wird als Ausdruck für die Funktion ein einfacher Name (wie bespielsweise »f«) verwendet.
Die Semantik von new-Ausdrücken
Bei der Auswertung eines new-Ausdrucks wird die durch den Ausdruck direkt hinter »new« angegebene Funktion aufgerufen.
Der Wert und die Wirkung einer Auswertung eines new-Ausdrucks wird durch jene Funktions festgelegt.
Der Aufruf einer Funktion mit »new«, wie in »(new f())«, kann ein anderes Verhalten zeigen als der Aufruf derselben Funktion ohne »new«, wie in »(f())«; insbesondere ergibt der Aufruf einer Funktion mit »new« immer ein neues Verzeichnis.
Der Wert eines new-Ausdrucks ist ein neues Verzeichnis.
Der new-Ausdruck ohne Argumentangabe (wie in »( new f )«) hat dieselbe Bedeutung wie ein new-Ausdruck mit Argumentangabe, aber ohne Ausdruckliste (wie in »( new f() )«).
Nicht jede Funktion darf mit »new« aufgerufen werden: Eine Funktion, die mit »new« aufgerufen werden kann, wird Konstruktor genannt.
- Protokoll
f = ()=> Console.log( "f wurde aufgerufen." )
function f()
new f
TypeError: f is not a constructor
Wir werden bald schon vordefinierte Konstruktoren kennenlernen und später auch das Schreiben von Konstruktoren erlernen.
Verzeichnisse werden in JavaScript auch als Objekte bezeichnet.
Ein Objekt, das mit einem Konstruktor »f« erzeugt wurde, nennt man auch ein „f-Objekt “.
Die Priorität von »new« ist so hoch, daß der Erzeugungsausdruck meist nicht eingeklammert werden muß.
Im Gegensatz zu »Math« existieren mit »new« erzeugte Verzeichnisse nur vorübergehend (solange, wie sie auch verwendet werden).
Anhang mit Notizen
Posting von August 2019
In JavaScript ist es einfach, Objekte zur Laufzeit zu
erweitern.
main.js
class VorgegebeneKlasse
{ constructor(){ this.title = 'Vorgegebener Titel'; }
getTitle(){ return this.title; }}
termine1 = [ new VorgegebeneKlasse() ]; i = 0;
titel = termine1[i].getTitle();
print( titel );
termine1[ 0 ].name = 'Mein zusaetzlicher Name';
Object.getPrototypeOf( termine1[ 0 ] ).getName =
function(){ return this.name; };
print( termine1[ 0 ].getName() );
transcript
Vorgegebener Titel
Mein zusaetzlicher Name
Ich habe oben das Feld »name« zum Objekt »termine1[ 0 ]«
hinzugefügt. Die Methode »getName« hätte auch auf diese
Weise zu jenem Objekt hinzugefügt werden können. Ich habe
sie aber statt dessen zum Prototyp jenes Objekts hinzugefügt,
um auch diese Möglichkeit einmal zu zeigen - so kann jene
Methode von allen Objekten mit jenem Prototyp genutzt werden.
Hatte ich übersehen. Am Ende meines vorherigen Skripts
kann man noch die folgenden drei Zeilen anhängen.
termine1[ 0 ].event =
{ title: "Mein Titel", getTitle(){ return this.title; } }
print( termine1[i].event.getTitle() )
transcript
Mein Titel
Wobei solche "get"-Funktionen in JavaScript vielleicht
weniger idiomatisch sind als die direkte Verwendung von
Eigenschaften, wie in
event.title
, da JavaScript getter-Funktionen direkt unterstützt und es
so erlaubt, bei Bedarf getter-Funktionen für Eigenschaften zu
erstellen.
main.js
event = { title: "Mein Titel" };
print( event.title );
Object.defineProperty
( event, "title_", Object.getOwnPropertyDescriptor( event, "title" ));
delete event[ "title" ];
Object.defineProperty
( event, 'title',
{ get: function() { return '"' + this.title_ + '"'; } });
print( event.title )
transcript
Mein Titel
"Mein Titel"
Dabei sollen die beiden mittleren Anweisungen des Skriptes
nur die bisherige Eigenschaft "title" in "title_" umbenennen
und können entfallen, wenn man in den ersten beiden
Anweisungen gleich von Anfang an "title_" verwendet:
main.js
event = { title_: "Mein Titel" }
print( event.title_ )
Object.defineProperty
( event, 'title', { get: function() { return '"' + this.title_ + '"'; } });
print( event.title )
transcript
Mein Titel
"Mein Titel"