Parameter in Funktionsausdrücken (Parameter in Funktionsausdrücken), Lektion, Seite 723576
https://www.purl.org/stefan_ram/pub/parameter_funktionsausdruck_javascript (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
JavaScript-Kurs

Parameterdeklarationen  in Funktionsausdrücken in JavaScript 

Die Schreibweise » x =>« kann wie »()=>« verwendet werden, ergibt aber eine Funktion mit einem Parameter, zu deren Aufruf ein Argument nötig ist.

Ein Funktionsausdruck mit einem Parameter
Ausdruck
.------------. .--. .----------.
--->| Bezeichner |ooo>( => )--->| Ausdruck |--->
'------------' '--' '----------'

Zwischen dem Bezeichner und dem Pfeilsymbol »=>« darf die Zeile nicht beendet werden.

Auswertung
x => 1
function ()
Auswertung
( x => 1 )( 2 )
1

Im inneren Ausdruck des Funktionsausdrucks (rechts vom Pfeil »=>«) steht der Name »x« für den Wert des Arguments.

Auswertung
( x => x )( 2 )
2

Der Wert des Parameters »x« in der obigen Anwendung der Pfeilfunktion beträgt «2». Aber dieser Wert wird nicht dauerhaft, wie ein globaler Eintrag, gespeichert, sondern nur vorübergehend während der Anwendung der Pfeilfunktion auf einen Argumentwert. Dazu wird vorübergehend eine Kopie der Pfeilfunktion erstellt, in welcher der Parametername an den Argumentwert gebunden ist. Von außerhalb der Pfeilfunktion kann nicht direkt auf den Wert des Parameters der Pfeilfunktion zugegriffen weren.

Auswertung
( x => 1 + x )( 2 )
3
Auswertung
( x => x + x )( 4 + 2 )
12

Der Parameter muß nicht immer den Namen »x« haben. Auch andere Namen, wie »o« oder »Wert« sind möglich, solange sie nicht mit anderen, schon verwendeten Namen in Konflikt geraten. (Dies wird auch als „Alpha-Äquivalenz “ bezeichnet.)

Auswertung
( o => 1 + o )( 2 )
3
Auswertung
( Wert => 1 + Wert )( 2 )
3

Etwas, das einen Parameter hat, nennt man – wie schon früher einmal erwähnt – manchmal auch „parametrisiert “. Wir sahen oben also parametrisierte Pfeilfunktionen. Etwas, das keinen Parameter hat, nennt man – wie schon früher einmal erwähnt – manchmal auch „parameterlos “.

Ein Parameter ist keine Eigenschaft des globalen Objektes, sondern ein davon unabhängiger Name für einen Wert (für den Wert des Arguments, mit dem die Funktion aufgerufen wurde).

Deklarationen

Wenn ein Name an einer Stelle verwendet wird, die extra dafür gedacht ist, diesen Namen für einen bestimmten Zweck einzuführen, so nennt man dies auch eine Deklaration  des Namens. In »x => 1« wird also ein Parameter »x« deklariert.

Auswertung
x => 1
function ()

Bezeichner

Als Name in einer Deklaration (hier also als Parameternamen) sind fast alle Bezeichnernamen erlaubt. (Der Begriff wurde schon vorgestellt, es handelt sich vereinfacht gesagt um eine Folge von Buchstaben, die ab der zweiten Position auch Ziffern enthalten darf.)

Genauer gesagt, muß der Name ein Bezeichner  sein. Wir hatten diesen Begriff auch schon eingeführt, aber damals den Unterschied zu einem Bezeichnernamen noch nicht behandelt.

Ein Bezeichner  ist ein Bezeichnername, der kein reserviertes Wort  ist.

Reservierte Wörter, wie »in« (ein schon vorgestellter Operator), dürfen nicht als Namen von Konstanten verwendet werden, obwohl sie als Namen von Eigenschaften verwendet werden können.

Konsole
in => 0
SyntaxError: expected expression, got keyword 'in'
Konsole
x => 0
function ()

Hier listen wir einige Wörter auf, die nicht als Konstante deklariert werden dürfen. Es handelt sich dabei hauptsächlich um reservierte Wörter. (Weitere Details findet man in ECMAScript 2016, 11.6.2 und 12.1.)

Schlüsselwörter
break do in typeof case else instanceof var catch export new void class extends return while const finally super with continue for switch yield debugger function this default if throw delete import try
zukünftige Schlüsselwörter
enum await
nicht erlaubte Literale
null true false

Benennung parametrisierter Funktionen

Parametrisierte Funktionen können wie nicht-parametrisierte Funktion auch benannt  werden.

Auswertung
f = x => typeof x
function f()
Auswertung
f( 2 )
"number"
Auswertung
f( "2" )
"string"

Fehlende Argumente

Wird für ein Parameter kein Argumentwert angegeben, so erhält der Parameter den Wert «undefined».

Auswertung
( x => x )()
undefined

(Dies kann verwendet werden, um den Wert «undefined» zu erhalten, selbst wenn »this.undefined« umdefiniert worden sein könnte.)

Wird «undefined» in Rechnungen verwendet, kann sich dann beispielsweise der Wert «NaN» ergeben.

Auswertung
( x => 1 + x )()
NaN

Überzählige Argumente

Wird ein Argumentwert angegeben, obwohl eine Funktion gar keinen Parameter hat, wird der Argumentwert ignoriert.

Auswertung
( ()=> 2 )( 3 )
2

Das überzählige Argument wird ausgewertet, obwohl der sich ergebende Wert ignoriert wird.

Auswertung
( ()=> 2 )( console.log( "abc" ))

abc

2

Auch mehrere  überzählige Argumente werden ausgewertet.

Auswertung
( ()=> console.log( "ghi" ))( console.log( "abc" ), console.log( "def" ))

abc

def

ghi

undefined

Lokale Namen

Parameter sind lokale Namen und keine globalen Einträge. Sie können nur innerhalb der definierten Funktion verwendet werden. Sie gehören zu der „lexikalischen Umgebung“ dieser Funktion, welche aber kein Verzeichnis ist, auf das man direkt zugreifen kann.

Für globale Einträge verwenden wir in diesem Kurs bevorzugt kurze Namen, weil diese meist noch unbelegt sind. Für lokale Namen, wie Parameter, können aber ohne Bedenken auch längere Namen verwendet werden.

Auswertung
f = wertDessenTypErmitteltWerdenSoll => typeof wertDessenTypErmitteltWerdenSoll
function f()

Parameter verdecken globale Einträge

Wenn es sowohl einen Parameter als auch einen globalen Eintrag mit dem gleichen Namen gibt, dann steht jener Name innerhalb einer Funktion (rechts vom Pfeil »=>«) für den Parameter.

Zuweisung an eine globale Eigenschaft
this.x = 1
undefined
Auswertung
f = x => x
function f()
Auswertung
f( 2 )
2

Um den globalen Eintrag zu erreichen kann eine Qualifikation mit »this« verwendet werden.

Auswertung
f = x => this.x
function f()
Auswertung
f( 2 )
1

Das defensive »window.« ⃗

Wenn (versehentlich oder absichtlich) »alert« als Parametername verwendet wird, dann hat »alert( 22 );« (rechts vom Pfeil »=>«) nicht mehr unbedingt die beabsichtigte Wirkung, während »window.alert« von der Umdefinition unbeeinflußt bleibt.

In der folgende Folge von Auswertungen öffnet der Aufruf »f( x=>x )« kein Meldungsfenster mehr, während »g( x=>x )« weiterhin ein Meldungsfenster öffnet.

Auswertung
f = alert => alert( 22 );
function f()
Auswertung
g = alert => window.alert( 24 );
function g()
Auswertung
f( x=>x )
22
Auswertung
g( x=>x )
[24]
undefined

Es könnte zwar auch sein, daß jemand »window« umdefiniert, doch ist »window« so prominent, daß dies weniger wahrscheinlich ist als eine Umdefinition von »alert«. Deswegen ist es vermutlich etwas sicherer »window.alert« statt »alert« zu verwenden.

Berechnete Namen ⃗

Wir können nun eine Funktion »d« schreiben, die Zahlen in deutsche Wörter übersetzt.

Auswertung
d0 = "Null"
"Null"
Auswertung
d1 = "Eins"
"Eins"
Auswertung
d = x => eval( "d" + x )
function d()
Auswertung
d( 0 )
"Null"
Auswertung
d( 1 )
"Eins"

Die hier gezeigt Verwendung von »eval« gilt in JavaScript  eigentlich nicht  als guter Stil, da es für das Anlegen solcher Zuordnungen in JavaScript  auch Möglichkeiten ohne »eval« gibt, die dafür bevorzugt eingesetzt werden sollten. Weil wir jene Möglichkeiten aber bisher noch nicht kennengelernt haben, können wir vorübergehend »eval« für solche Zwecke einsetzen. Außerdem ist das obige Beispiel zum Verständnis der Sprache hilfreich – auch wenn wir später noch bessere Lösungen für Zuordnungen von Texten zu Zahlen kennenlernen werden.

Beispiel Eine Funktion, die ergibt, ob ihr Argumenwert »NaN« ist ⃗

Auswertung
is_NaN = x => x !== x
function is_NaN()
Auswertung
is_NaN( 2 )
false
Auswertung
is_NaN( NaN )
true

Blockfunktionen mit Parametern ⃗

Etwaige Parameter der Funktion können in dem Block verwendet werden.

Auswertung
f = x =>{ console.log( "abc" ); console.log( x ); }
function f()
Auswertung
f( "012" )

abc

012

undefined

Zuweisungen an Parameter ⃗

Einem Parameter einer Funktion kann innerhalb dieser Funktion auch ein Wert zugewiesen werden.

Auswertung
f = x =>{ x = x + 2; console.log( x ); x = x + 2; console.log( x ); }
function f()
f( 3 )

5

7

Wir hatten früher einen Parameter als einen Namen für einen Wert bezeichnet. Da wird jetzt aber sehen, daß der Wert eines Parameter auch durch eine Zuweisung verändert werden kann, müssen wir den Parameter jetzt als Name für einen Speicherplatz ansehen, der zunächst den Wert des Arguments erhält, aber dem dann innerhalb der Funktion auch ein anderer Wert zugewiesen werden kann.

Schleifen ⃗

main.js

VierMal = f =>{ f(); f(); f(); f(); }

VierMal( () => print( "Hallo!" ) )

Protokoll

Hallo!

Hallo!

Hallo!

Hallo!

Rekursion ⃗

Bereits innerhalb einer Funktion kann der interne Name der Funktion (also ihr name-Eintrag) verwendet werden, damit die Funktion sich selbst aufrufen kann. Diese sogenannte Rekursion könnte den Browser allerdings blockieren, da die Funktion sich ohne Ende immer wieder selber aufruft. Wir werden erst später lernen, wie solch eine Rekursion besser gesteuert werden kann.

Auswertung
f = x =>{ x = x + 2; console.log( x ); f( x ); }
function f()
f.name
"f"
f( 3 )

5

7

9

11

InternalError: too much recursion

Durch die Rekursion wird eine neue Inkarnation der Funktion angelegt, während eine Inkarnation bereits aktiv ist. Dies geht immer so weiter, und jede neue Inkarnation benötigt unter vielen JavaScript -Implementation eigenen Speicherplatz. Daher ist nach einer Weile kein Speicherplatz mehr vorhanden, und die Rekursion bricht dann doch ab.

Das folgende Konsolenprotokoll zeigt, wie die Rekursion doch mit unseren Mitteln auf 10 Schritte begrenzt werden könnte.

Konsole
f0 = x =>{ x = x + 1; console.log( x ); eval( "f" + Math.floor( x/10 )+ "( x )" ); }
function f0()
f1 = x =>{ }
function f1()
f0( 0 )

1

2

3

4

5

6

7

8

9

10

undefined

Unmittelbare Aufrufe von Funktionen *

Ein Programmteil, der einen Wert vorübergehend unter einem globalen Schlüssel, wie »x«, abspeichern will, kann nicht sicher sein, ob dieser Schlüssel nicht schon von einem anderen Programmteil verwendet wird.

Statt dessen kann auch ein Parameter einer Funktion verwendet werden, die mit einem Pfeil angegeben und sofort aufgerufen wird.

Auswertung
( x =>{ x = 2; console.log( x + 3 ); } )()
5 

Der globale Schlüssel »x« ist nach der obenstehenden Auswertung weiterhin undefiniert, weil der Name »x« im obigen Block für den nur vorübergehend angelegten Parameter »x« steht.

Auswertung
x
ReferenceError: x is not defined

Obwohl Parameter in der Praxis selten als Variablen verwendet werden, kommt der sofortige Aufruf von angegebenen Funktionen in JavaScript  bei fortgeschrittenen Programmierern relativ häufig vor.

Rückgabe einer neuen Funktion *

Eine Funktion kann auch eine Funktion als Ergebnis  haben.

Die Funktion »plus« ergibt eine Funktion, welche eine Zahl »x« um den als Argument beim Aufruf von »inc« angegebenen Wert »a« erhöht und dann ausgibt.

Auswertung
plus = a => x => { console.log( x + a ); };
function inc()
Auswertung
plus3 = inc( 3 );
function inc/<()

Die Funktion »plus3« ist nun »x => { console.log( x + 3 ); }«.

Auswertung
plus3( 8 )
11
Auswertung
plus2 = inc( 2 );
function inc/<()

Die Funktion »plus2« ist nun »x => { console.log( x + 2 ); }«.

Auswertung
plus2( 8 )
10

Wir können erkennen, daß »plus3« und »plus2« zwei verschiedene Funktionen sind.

Auswertung
plus3 === plus2
false

Die Funktion »plus« erzeugt also bei jedem Aufruf eine neue Funktion.

Ausdrücke für bestimmte Werte ⃗

In älteren JavaScript -Implementationen konnte man globale Einträge, wie »this.Infinity« und »this.undefined« umdefinieren. Wir zeigen hier Ausdrücke, die auch dann verwendet werden könne, um den Wert »Infinity« beziehungsweise »undefined« auszudrücken.

Ausdruck mit dem Wert »Infinity«
(1/0)
Ausdruck mit dem Wert »undefined«
((x=>x)())
Ausdruck mit dem Wert »NaN«
(+"a")

Übungsfragen

?   Übungsfrage

Warum hat der Ausdruck »((x=>x)())« den Wert »undefined«?

?   Übungsfragen

Können Sie die Werte der folgenden Ausdrücke vorhersagen?

Ausdruck
( x => 4 )( 3 )
Ausdruck 1
( x => x )( 9 )
Ausdruck 2
( o => o )( 9 )
Ausdruck 3
( x => 2 + x )( 3 )
Ausdruck 4
( x => x / 2 )( 8 )
Ausdruck 5
( x => x + x )( 10 + 2 )
Ausdruck 6 *
( x => y => x - y )( 5 )( 8 )
Ausdruck 7 *
( f => f( 2 ))( x => x * x )
Ausdruck 8 *
( f => x => f( x ))( x => x * x )( 3 )

?   Übungsfrage

Welchen Wert hat der Aufruf »g()« am Ende der folgenden Eingaben?

Eingaben

g = ()=> 2 + f( 3 )

f = x => 10 * x

g()

Übungsaufgaben

/   Übungsaufgabe

Schreiben Sie eine Funktion namens »f«, deren Ergebnis um «1» größer ist als der Wert ihres Arguments.

Die Lösung sollte aussehen wie »f = x => «, wobei dann an Stelle der Ellipse noch etwas einzusetzen ist.

Wenn die Funktion richtig definiert wurde, sollten danach folgende Auswertungen beobachtbar sein.

Auswertung
f( 2 )
3
Auswertung
f( 10 )
11

/   Übungsaufgabe

Schreiben Sie eine Funktion »q«, die das Quadrat einer Zahl berechnet.

Auswertung
q( 2 )
4
Auswertung
q( 3 )
9

/   Übungsaufgabe

Schreiben Sie eine Funktion »c«, die als Abkürzung von »console.log« verwendet werden kann.

/   Übungsaufgabe

Definieren Sie eine Wirkfunktion »f«, die den ihr übergebenen Argumentwert und den um Eins vermehrten Argumentwert mit »console.log« auf insgesamt zwei Zeilen ausgibt.

Auswertung
f( 14 )

14

15

undefined

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram723576 stefan_ram:723576 Parameter in Funktionsausdrücken Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723576, slrprddef723576, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/parameter_funktionsausdruck_javascript