From 4ab365b110f2f1f2b736326b7059244a32115089 Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 14:45:38 +0100 Subject: unslug de: move --- .../guide/ausdruecke_und_operatoren/index.html | 965 --------------------- .../control_flow_and_error_handling/index.html | 430 +++++++++ .../guide/details_of_the_object_model/index.html | 721 +++++++++++++++ .../javascript/guide/einf\303\274hrung/index.html" | 140 --- .../guide/expressions_and_operators/index.html | 965 +++++++++++++++++++++ .../guide/feinheiten_des_objektmodells/index.html | 721 --------------- files/de/web/javascript/guide/functions/index.html | 657 ++++++++++++++ .../de/web/javascript/guide/funktionen/index.html | 657 -------------- .../javascript/guide/grammar_and_types/index.html | 699 +++++++++++++++ .../guide/grammatik_und_typen/index.html | 699 --------------- .../web/javascript/guide/introduction/index.html | 140 +++ .../kontrollfluss_und_fehlerbehandlung/index.html | 430 --------- .../guide/loops_and_iteration/index.html | 337 +++++++ .../guide/mit_objekten_arbeiten/index.html | 506 ----------- .../guide/schleifen_und_iterationen/index.html | 337 ------- .../javascript/guide/text_formatting/index.html | 257 ++++++ .../javascript/guide/textformatierung/index.html | 257 ------ .../guide/working_with_objects/index.html | 506 +++++++++++ 18 files changed, 4712 insertions(+), 4712 deletions(-) delete mode 100644 files/de/web/javascript/guide/ausdruecke_und_operatoren/index.html create mode 100644 files/de/web/javascript/guide/control_flow_and_error_handling/index.html create mode 100644 files/de/web/javascript/guide/details_of_the_object_model/index.html delete mode 100644 "files/de/web/javascript/guide/einf\303\274hrung/index.html" create mode 100644 files/de/web/javascript/guide/expressions_and_operators/index.html delete mode 100644 files/de/web/javascript/guide/feinheiten_des_objektmodells/index.html create mode 100644 files/de/web/javascript/guide/functions/index.html delete mode 100644 files/de/web/javascript/guide/funktionen/index.html create mode 100644 files/de/web/javascript/guide/grammar_and_types/index.html delete mode 100644 files/de/web/javascript/guide/grammatik_und_typen/index.html create mode 100644 files/de/web/javascript/guide/introduction/index.html delete mode 100644 files/de/web/javascript/guide/kontrollfluss_und_fehlerbehandlung/index.html create mode 100644 files/de/web/javascript/guide/loops_and_iteration/index.html delete mode 100644 files/de/web/javascript/guide/mit_objekten_arbeiten/index.html delete mode 100644 files/de/web/javascript/guide/schleifen_und_iterationen/index.html create mode 100644 files/de/web/javascript/guide/text_formatting/index.html delete mode 100644 files/de/web/javascript/guide/textformatierung/index.html create mode 100644 files/de/web/javascript/guide/working_with_objects/index.html (limited to 'files/de/web/javascript/guide') diff --git a/files/de/web/javascript/guide/ausdruecke_und_operatoren/index.html b/files/de/web/javascript/guide/ausdruecke_und_operatoren/index.html deleted file mode 100644 index 7a0e723c6c..0000000000 --- a/files/de/web/javascript/guide/ausdruecke_und_operatoren/index.html +++ /dev/null @@ -1,965 +0,0 @@ ---- -title: Ausdrücke und Operatoren -slug: Web/JavaScript/Guide/Ausdruecke_und_Operatoren -tags: - - Beginner - - Extensions - - Guide - - JavaScript - - Operatoren - - 'l10n:priority' -translation_of: Web/JavaScript/Guide/Expressions_and_Operators ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Funktionen", "Web/JavaScript/Guide/Numbers_and_dates")}}
- -

Dieses Kapitel beschreibt JavaScript Ausdrücke und Operatoren, Zuweisungsoperatoren, Vergleichsoperatoren, Rechenoperatoren, Bit-Operatoren, Logische Operatoren, Operator zur Zeichenkettenverknüpfung, Bedingte (ternäre) Operatoren und mehr.

- -

Eine vollständige und detaillierte Liste mit Operatoren und Ausdrücken ist in den Referenzen zu finden.

- -

Operatoren

- -

JavaScript besitzt verschiedene Operatortypen. Dieser Abschnitt beschreibt die einzelnen Operatoren und beinhaltet Informationen über die Operator-Prioritäten.

- - - -

JavaScript verfügt über beides, binäre als auch unäre Operatoren. Zudem existiert ein spezieller ternärer Operator - der Bedingungsoperator. Ein binärer Operator benötigt zwei Operanden, einen vor dem Operator und einen nach dem Operator:

- -
operand1 operator operand2
-
- -

Zum Beispiel: 3+4, oder x*y.

- -

Ein unärer Operator erwartet einen einzelnen Operanden, entweder vor, oder nach dem Operator:

- -
operator operand
-
- -

oder

- -
operand operator
-
- -

Zum Beispiel: x++, oder ++x.

- -

Zuweisungsoperatoren

- -

Ein Zuweisungsoperator weißt seinem linken Operanden einen Wert zu. Dieser Wert basiert auf dem Ergebnis des rechten Operanden. Der einfachste Zuweisungsoperator ist das "Gleich" (=), welches den Wert des rechten Operanden dem linken Operanden zuweist.

- -

Zum Beispiel: x = y (y wid der Wert von x zugewiesen).

- -

Es gibt auch zusammengesetzte Zuweisungsoperatoren, diese stellen Abkürzungen für die in der folgenden Tabelle aufgelisteten Operationen dar:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Zusammengesetzte Zuweisungsoperatoren
NameAbgekürzter OperatorAusgeschriebener Operator
Zuweisungx = yx = y
Additionx += yx = x + y
Subraktionx -= yx = x - y
Multiplikationx *= yx = x * y
Divisionx /= yx = x / y
Modulo (Division mit Rest)x %= yx = x % y
Exponentiation assignment {{experimental_inline}}x **= yx = x ** y
Left shift assignmentx <<= yx = x << y
Right shift assignmentx >>= yx = x >> y
Unsigned right shift assignmentx >>>= yx = x >>> y
Bitwise AND assignmentx &= yx = x & y
Bitwise XOR assignmentx ^= yx = x ^ y
Bitwise OR assignmentx |= yx = x | y
- -

Destrukturierung

- -

Komplexere Zuweisungen ermöglicht Javascript über die sogenannte Destrukturierung. Diese ermöglicht es, Daten aus Arrays oder Objekten mithilfe einer Syntax zu extrahieren, die die Konstruktion von Array- und Objektliteralen widerspiegelt.

- -
var foo = ["eins", "zwei", "drei"];
-
-// Ohne Destrukturierung
-var eins   = foo[0];
-var zwei   = foo[1];
-var drei   = foo[2];
-
-// mit Destrukturierung
-var [eins, zwei, drei] = foo;
- -

Vergleichsoperatoren

- -

Ein Vergleichsoperator vergleicht seine Operanden und gibt einen logischen Wert zurück, der darauf basiert, ob der Vergleich wahr ist, oder nicht.

- -

Die Operanden können numerische-, string-, logische- oder Objektwerte sein. Zeichenfolgen werden basierend auf der lexikographischen Standardreihenfolge mit unicodewerten verglichen. Wenn die beiden Operanden nicht vom selben Typ sind, versucht JavaScript in den meisten Fällen, sie in einen geeigneten Typ für den Vergleich zu konvertieren. Dieses Verhalten führt im Allgemeinen dazu, dass die Operanden numerisch verglichen werden. Die einzigen Ausnahmen für die Typumwandlung innerhalb von Vergleichen sind die Operatoren === und !==, die strenge Vergleiche durchführen. Diese Operatoren versuchen nicht, die Operanden in kompatible Typen zu konvertieren, bevor sie die Gleichheit überprüfen.

- -

Die folgende Tabelle beschreibt die Vergleichsoperatoren in Bezug auf diesen Beispielcode:

- -
var var1 = 3;
-var var2 = 4;
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Vergleichsoperatoren
OperatorBeschreibungBeispiele, die true zurückgeben
Equal (==)Gibt true zurück, wenn die Operanden gleich sind.3 == var1 -

"3" == var1

- 3 == '3'
Not equal (!=)Gibt true zurück, wenn die Operanden ungleich sind.var1 != 4
- var2 != "3"
Strict equal (===)Gibt true zurück, wenn die Operanden gleich sind und auch der Typ übereinstimmt. Weitere Informationen unter {{jsxref("Object.is")}} und sameness in JS.3 === var1
Strict not equal (!==)Gibt true zurück, wenn die Operanden vom selben Typ sind, doch nicht den selben Wert haben, oder wenn sie den selben Wert haben, doch nicht vom selben Typ sind.var1 !== "3"
- 3 !== '3'
Greater than (>)Gibt true zurück, wenn der linke Operand größer dem rechten Operanden ist.var2 > var1
- "12" > 2
Greater than or equal (>=)Gibt true zurück, wenn der linke Operand größer als, oder gleich dem linken Operanden ist.var2 >= var1
- var1 >= 3
Less than (<)Gibt true zurück, wenn der linke Operand kleiner dem rechten Operanden ist.var1 < var2
- "2" < 12
Less than or equal (<=)Gibt true zurück, wenn der linke Operand kleiner als, oder gleich dem rechten Operanden ist.var1 <= var2
- var2 <= 5
- -
-

Note: (=>) ist kein Operator, hiermit werden Arrow functions notiert.

-
- -

Arithmetische Operatoren (Rechenzeichen)

- -

Ein arithmetischer Operator nimmt numerische Werte (Literale oder Variablen) als Operanden entgegen und gibt einen einzelnen numerischen Wert zurück. Die arithmetischen Standardoperatoren sind Addition (+), Subtraktion (-), Multiplikation (*) und Division (/). Diese Operatoren funktionieren wie in den meisten anderen Programmiersprachen, wenn sie mit Fließkommazahlen verwendet werden (beachten Sie insbesondere, dass die Division durch Null {{jsxref ("Infinity")}} ergibt).

- -
1 / 2; // 0.5
-1 / 2 == 1.0 / 2.0; // this is true
-
- -

Neben den arithmetischen Standardoperatoren (+, -, * /), stellt JavaScript noch weitere Rechenzeichen zur Verfügung. Diese werden in der folgenden Tabelle aufgeführt:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Arithmetische Operatoren
OperatorBeschreibungBeispiel
Remainder (%)Binärer Operator. Gibt den ganzzahligen Rest der Division beider Operanden zurück.12 % 5 gibt 2 zurück.
Increment (++) -

Unärer Operator. Addiert 1 zu seinem Operanden.

- -

Wenn der Operator vorangestellt wird (++x), gibt er den Wert seines Operanden zurück nachdem 1 addiert wurde; Wenn der Operator nachgestellt wird (x++), gibt er den Wert seines Operanden zurück, bevor 1 addiert wurde.

-
Wenn x gleich 3 ist, setzt ++x x auf 4 und gibt 4 zurück, wobei x++  3 zurückgibt und erst danach x auf 4 setzt.
Decrement (--) -

Unärer Operator. Subtrahiert 1 von seinem Operanden.

- -

Der Rückgabewert verhält sich analog zum increment Operator.

-
Wenn x gleich 3 ist, setzt --x x auf 2 und gibt 2 zurück, wobei x-- 3 zurückgibt und erst danach, x auf 2 setzt.
Unary negation (-)Unärer Operator. Gibt die Negierung seines Operanden zurück.Wenn x gleich 3 ist, gibt -x -3 zurück.
Unary plus (+)Versucht, den Operanden in eine Zahl umzuwandeln, wenn dies nicht bereits der Fall ist.+"3" gibt 3 zurück.
- +true gibt 1 zurück.
Exponentiation operator (**) {{experimental_inline}}Calculates the base to the exponent power, that is, baseexponent2 ** 3 gibt 8 zurück.
- 10 ** -1 gibt 0.1 zurück.
- -

Bitweise Operatoren

- -

Ein bitweiser Operator behandelt seine Operanden als eine Menge von 32 Bits (Nullen und Einsen) und nicht als dezimale, hexadezimale oder oktale Zahlen. Zum Beispiel hat die Dezimalzahl Neun eine binäre Darstellung von 1001. Bitweise Operatoren führen ihre Operationen mit solchen binären Darstellungen aus, doch sie geben standardmäßige numerische JavaScript-Werte zurück.

- -

Die folgende Tabelle fasst die bitweisen Operatoren von JavaScript zusammen.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bitweise Operatoren
OperatorVerwendungBeschreibung
Bitwise ANDa & bReturns a one in each bit position for which the corresponding bits of both operands are ones.
Bitwise ORa | bReturns a zero in each bit position for which the corresponding bits of both operands are zeros.
Bitwise XORa ^ bReturns a zero in each bit position for which the corresponding bits are the same.
- [Returns a one in each bit position for which the corresponding bits are different.]
Bitwise NOT~ aInverts the bits of its operand.
Left shifta << bShifts a in binary representation b bits to the left, shifting in zeros from the right.
Sign-propagating right shifta >> bShifts a in binary representation b bits to the right, discarding bits shifted off.
Zero-fill right shifta >>> bShifts a in binary representation b bits to the right, discarding bits shifted off, and shifting in zeros from the left.
- -

Bitweise logische Operatoren

- -

Konzeptuell arbeiten bitweise logische Operatoren wie folgt:

- - - -

Zum Beispiel ist die binäre Darstellung der Zahl neun 1001, die binäre Darstellung der Zahl 15 ist 1111. Wenn die bitweisen logischen Operatoren auf diese Zahlen angewendet werden, ergeben sich folgende Ergebnisse:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Beispiele für bitweise Operatoren
AusdruckErgebnisBinäre Darstellung
15 & 991111 & 1001 = 1001
15 | 9151111 | 1001 = 1111
15 ^ 961111 ^ 1001 = 0110
~15-16~00000000...00001111 = 11111111...11110000
~9-10~00000000...00001001 = 11111111...11110110
- -

Beachte, dass alle 32 Bits invertiert werden, wenn der bitweise NOT Operator benutzt wird. Wenn dabei das höchstwertigste (ganz linke) Bit auf 1 gesetzt wird, entsteht eine negative Zahl. Note that all 32 bits are inverted using the Bitwise NOT operator, and that values with the most significant (left-most) bit set to 1 represent negative numbers (Zweierkomplement). ~x wird also genauso ausgewertet wie -x - 1.

- -

Bitweise Schiebeoperatoren

- -

Die bitweisen Schiebeoperatoren erwarten zwei Operanden. Der erste ist der Wert, der geschoben werden soll, der zweite die Anzahl der Bits, um die geschoben werden soll. Die Richtung, in die geschoben wird, wird durch den verwendeten Operator bestimmt.

- -

Schiebeoperatoren konvertieren ihre Operanden in 32 Bit Integer Zahlen und liefern als Ergebnis einen Wert vom selben Typen wir der linke Operand.

- -

Die Schiebeoperatoren sind in der folgenden Tabelle aufgelistet.

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bitwise shift operators
OperatorDescriptionExample
Left shift
- (<<)
This operator shifts the first operand the specified number of bits to the left. Excess bits shifted off to the left are discarded. Zero bits are shifted in from the right.9<<2 yields 36, because 1001 shifted 2 bits to the left becomes 100100, which is 36.
Sign-propagating right shift (>>)This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Copies of the leftmost bit are shifted in from the left.9>>2 yields 2, because 1001 shifted 2 bits to the right becomes 10, which is 2. Likewise, -9>>2 yields -3, because the sign is preserved.
Zero-fill right shift (>>>)This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Zero bits are shifted in from the left.19>>>2 yields 4, because 10011 shifted 2 bits to the right becomes 100, which is 4. For non-negative numbers, zero-fill right shift and sign-propagating right shift yield the same result.
- -

Logische Operatoren

- -

Logische Operatoren werden normalerweise mit boolesche (logischen) Werten verwendet - hierbei geben sie dann einen booleschen Wert zurück. Die Operatoren && und || geben den Wert von einem der Operatoren zurück, sodass sie im Falle der Verwendung mit einem nicht-booleschen Wert auch einen nicht-booleschen Wert zurückgeben können. Die logischen Operatoren werden in der folgenden Tabelle beschrieben: 

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Logische Operatoren
OperatorVerwendungBeschreibung
Logical AND (&&)expr1 && expr2Gibt expr1 zurück, sofern es zu false konvertiert werden kann; ansonsten wird expr2 zurückgegeben. Insofern mit booleschen Werten verwendet, && gibt true zurück, wenn beide Operanden wahr sind; ansonsten false.
Logical OR (||)expr1 || expr2 -

Gibt expr1 zurück, sofern er zu true konvertiert werden kann. Insofern mit booleschen Werten verwendet, gibt der Operator || true zurück, wenn einer von beiden Operanden true ist; wenn beide false sind, wird false zurückgegeben. 

-
Logical NOT (!)!expr -

Gibt false zurück, wenn sein einziger Operand in true konvertiert werden kann; andernfalls gibt er true zurück. 

-
- -

Beispiele von Ausdrücken, die in false umgewandelt werden können, sind solche, die null, 0, NaN, einen leeren String ("") oder undefined sind. 

- -

Die folgenden Zeilen zeigen Beispiele des && (logisches UND) Operators.

- -
var a1 =  true && true;     // t && t returns true
-var a2 =  true && false;    // t && f returns false
-var a3 = false && true;     // f && t returns false
-var a4 = false && (3 == 4); // f && f returns false
-var a5 = "Cat" && "Dog";    // t && t returns Dog
-var a6 = false && "Cat";    // f && t returns false
-var a7 = "Cat" && false;    // t && f returns false
-
- -

Die folgenden Zeilen zeigen Beispiele des || (logisches ODER) Operators:

- -
var o1 =  true || true;     // t || t returns true
-var o2 = false || true;     // f || t returns true
-var o3 =  true || false;    // t || f returns true
-var o4 = false || (3 == 4); // f || f returns false
-var o5 = "Cat" || "Dog";    // t || t returns Cat
-var o6 = false || "Cat";    // f || t returns Cat
-var o7 = "Cat" || false;    // t || f returns Cat
-
- -

Die folgenden Zeilen zeigen Beispiele des ! (logisches NICHT) Operators:

- -
var n1 = !true;  // !t returns false
-var n2 = !false; // !f returns true
-var n3 = !"Cat"; // !t returns false
-
- -

Short-circuit-Bewertung 

- -

Da logische Ausdrücke von links nach rechts bewertet werden, werden sie auf eine mögliche "Abkürzung" (short-circuit) hin gemäß den folgenden Regeln evaluiert:

- - - -

Die Regeln der Logik garantieren, dass diese Bewertungen immer korrekt sind. Der irgendwas-Operand werden in den o.g. Beispielen hierbei nicht bewertet. 

- -

String-Operatoren

- -

In addition to the comparison operators, which can be used on string values, the concatenation operator (+) concatenates two string values together, returning another string that is the union of the two operand strings.

- -

For example,

- -
console.log("my " + "string"); // console logs the string "my string".
- -

The shorthand assignment operator += can also be used to concatenate strings.

- -

For example,

- -
var mystring = "alpha";
-mystring += "bet"; // evaluates to "alphabet" and assigns this value to mystring.
- -

Conditional (ternary) operator

- -

The conditional operator is the only JavaScript operator that takes three operands. The operator can have one of two values based on a condition. The syntax is:

- -
condition ? val1 : val2
-
- -

If condition is true, the operator has the value of val1. Otherwise it has the value of val2. You can use the conditional operator anywhere you would use a standard operator.

- -

For example,

- -
var status = (age >= 18) ? "adult" : "minor";
-
- -

This statement assigns the value "adult" to the variable status if age is eighteen or more. Otherwise, it assigns the value "minor" to status.

- -

Comma operator

- -

The comma operator (,) simply evaluates both of its operands and returns the value of the last operand. This operator is primarily used inside a for loop, to allow multiple variables to be updated each time through the loop.

- -

For example, if a is a 2-dimensional array with 10 elements on a side, the following code uses the comma operator to update two variables at once. The code prints the values of the diagonal elements in the array:

- -
var x = [0,1,2,3,4,5,6,7,8,9];
-var a = [x, x, x, x, x]
-
-for (var i = 0, j = 9; i <= j; i++, j--)
-  console.log("a[" + i + "][" + j + "]= " + a[i][j]);
-
- -

Unary operators

- -

A unary operation is an operation with only one operand.

- -

delete

- -

The delete operator deletes an object, an object's property, or an element at a specified index in an array. The syntax is:

- -
delete objectName;
-delete objectName.property;
-delete objectName[index];
-delete property; // legal only within a with statement
-
- -

where objectName is the name of an object, property is an existing property, and index is an integer representing the location of an element in an array.

- -

The fourth form is legal only within a with statement, to delete a property from an object.

- -

You can use the delete operator to delete variables declared implicitly but not those declared with the var statement.

- -

If the delete operator succeeds, it sets the property or element to undefined. The delete operator returns true if the operation is possible; it returns false if the operation is not possible.

- -
x = 42;
-var y = 43;
-myobj = new Number();
-myobj.h = 4;    // create property h
-delete x;       // returns true (can delete if declared implicitly)
-delete y;       // returns false (cannot delete if declared with var)
-delete Math.PI; // returns false (cannot delete predefined properties)
-delete myobj.h; // returns true (can delete user-defined properties)
-delete myobj;   // returns true (can delete if declared implicitly)
-
- -
Deleting array elements
- -

When you delete an array element, the array length is not affected. For example, if you delete a[3], a[4] is still a[4] and a[3] is undefined.

- -

When the delete operator removes an array element, that element is no longer in the array. In the following example, trees[3] is removed with delete. However, trees[3] is still addressable and returns undefined.

- -
var trees = ["redwood", "bay", "cedar", "oak", "maple"];
-delete trees[3];
-if (3 in trees) {
-  // this does not get executed
-}
-
- -

If you want an array element to exist but have an undefined value, use the undefined keyword instead of the delete operator. In the following example, trees[3] is assigned the value undefined, but the array element still exists:

- -
var trees = ["redwood", "bay", "cedar", "oak", "maple"];
-trees[3] = undefined;
-if (3 in trees) {
-  // this gets executed
-}
-
- -

typeof

- -

The typeof operator is used in either of the following ways:

- -
typeof operand
-typeof (operand)
-
- -

The typeof operator returns a string indicating the type of the unevaluated operand. operand is the string, variable, keyword, or object for which the type is to be returned. The parentheses are optional.

- -

Suppose you define the following variables:

- -
var myFun = new Function("5 + 2");
-var shape = "round";
-var size = 1;
-var today = new Date();
-
- -

The typeof operator returns the following results for these variables:

- -
typeof myFun;     // returns "function"
-typeof shape;     // returns "string"
-typeof size;      // returns "number"
-typeof today;     // returns "object"
-typeof dontExist; // returns "undefined"
-
- -

For the keywords true and null, the typeof operator returns the following results:

- -
typeof true; // returns "boolean"
-typeof null; // returns "object"
-
- -

For a number or string, the typeof operator returns the following results:

- -
typeof 62;            // returns "number"
-typeof 'Hello world'; // returns "string"
-
- -

For property values, the typeof operator returns the type of value the property contains:

- -
typeof document.lastModified; // returns "string"
-typeof window.length;         // returns "number"
-typeof Math.LN2;              // returns "number"
-
- -

For methods and functions, the typeof operator returns results as follows:

- -
typeof blur;        // returns "function"
-typeof eval;        // returns "function"
-typeof parseInt;    // returns "function"
-typeof shape.split; // returns "function"
-
- -

For predefined objects, the typeof operator returns results as follows:

- -
typeof Date;     // returns "function"
-typeof Function; // returns "function"
-typeof Math;     // returns "object"
-typeof Option;   // returns "function"
-typeof String;   // returns "function"
-
- -

void

- -

The void operator is used in either of the following ways:

- -
void (expression)
-void expression
-
- -

The void operator specifies an expression to be evaluated without returning a value. expression is a JavaScript expression to evaluate. The parentheses surrounding the expression are optional, but it is good style to use them.

- -

You can use the void operator to specify an expression as a hypertext link. The expression is evaluated but is not loaded in place of the current document.

- -

The following code creates a hypertext link that does nothing when the user clicks it. When the user clicks the link, void(0) evaluates to undefined, which has no effect in JavaScript.

- -
Click here to do nothing
-
- -

The following code creates a hypertext link that submits a form when the user clicks it.

- -

-Click here to submit
- -

Relational operators

- -

A relational operator compares its operands and returns a Boolean value based on whether the comparison is true.

- -

in

- -

The in operator returns true if the specified property is in the specified object. The syntax is:

- -
propNameOrNumber in objectName
-
- -

where propNameOrNumber is a string or numeric expression representing a property name or array index, and objectName is the name of an object.

- -

The following examples show some uses of the in operator.

- -
// Arrays
-var trees = ["redwood", "bay", "cedar", "oak", "maple"];
-0 in trees;        // returns true
-3 in trees;        // returns true
-6 in trees;        // returns false
-"bay" in trees;    // returns false (you must specify the index number,
-                   // not the value at that index)
-"length" in trees; // returns true (length is an Array property)
-
-// built-in objects
-"PI" in Math;          // returns true
-var myString = new String("coral");
-"length" in myString;  // returns true
-
-// Custom objects
-var mycar = { make: "Honda", model: "Accord", year: 1998 };
-"make" in mycar;  // returns true
-"model" in mycar; // returns true
-
- -

instanceof

- -

The instanceof operator returns true if the specified object is of the specified object type. The syntax is:

- -
objectName instanceof objectType
-
- -

where objectName is the name of the object to compare to objectType, and objectType is an object type, such as {{jsxref("Date")}} or {{jsxref("Array")}}.

- -

Use instanceof when you need to confirm the type of an object at runtime. For example, when catching exceptions, you can branch to different exception-handling code depending on the type of exception thrown.

- -

For example, the following code uses instanceof to determine whether theDay is a Date object. Because theDay is a Date object, the statements in the if statement execute.

- -
var theDay = new Date(1995, 12, 17);
-if (theDay instanceof Date) {
-  // statements to execute
-}
-
- -

Operator precedence

- -

The precedence of operators determines the order they are applied when evaluating an expression. You can override operator precedence by using parentheses.

- -

The following table describes the precedence of operators, from highest to lowest.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Operator precedence
Operator typeIndividual operators
member. []
call / create instance() new
negation/increment! ~ - + ++ -- typeof void delete
multiply/divide* / %
addition/subtraction+ -
bitwise shift<< >> >>>
relational< <= > >= in instanceof
equality== != === !==
bitwise-and&
bitwise-xor^
bitwise-or|
logical-and&&
logical-or||
conditional?:
assignment= += -= *= /= %= <<= >>= >>>= &= ^= |=
comma,
- -

A more detailed version of this table, complete with links to additional details about each operator, may be found in JavaScript Reference.

- -

Expressions

- -

An expression is any valid unit of code that resolves to a value.

- -

Every syntactically valid expression resolves to some value but conceptually, there are two types of expressions: with side effects (for example: those that assign value to a variable) and those that in some sense evaluate and therefore resolve to a value.

- -

The expression x = 7 is an example of the first type. This expression uses the = operator to assign the value seven to the variable x. The expression itself evaluates to seven.

- -

The code 3 + 4 is an example of the second expression type. This expression uses the + operator to add three and four together without assigning the result, seven, to a variable.
-
- JavaScript has the following expression categories:

- - - -

Primary expressions

- -

Basic keywords and general expressions in JavaScript.

- -

this

- -

Use the this keyword to refer to the current object. In general, this refers to the calling object in a method. Use this either with the dot or the bracket notation:

- -
this["propertyName"]
-this.propertyName
-
- -

Suppose a function called validate validates an object's value property, given the object and the high and low values:

- -
function validate(obj, lowval, hival){
-  if ((obj.value < lowval) || (obj.value > hival))
-    console.log("Invalid Value!");
-}
-
- -

You could call validate in each form element's onChange event handler, using this to pass it the form element, as in the following example:

- -

-
-

Enter a number between 18 and 99:

- -

- -

Grouping operator

- -

The grouping operator ( ) controls the precedence of evaluation in expressions. For example, you can override multiplication and division first, then addition and subtraction to evaluate addition first.

- -
var a = 1;
-var b = 2;
-var c = 3;
-
-// default precedence
-a + b * c     // 7
-// evaluated by default like this
-a + (b * c)   // 7
-
-// now overriding precedence
-// addition before multiplication
-(a + b) * c   // 9
-
-// which is equivalent to
-a * c + b * c // 9
-
- -

Comprehensions

- -

Comprehensions are an experimental JavaScript feature, targeted to be included in a future ECMAScript version. There are two versions of comprehensions:

- -
-
{{experimental_inline}} {{jsxref("Operators/Array_comprehensions", "[for (x of y) x]")}}
-
Array comprehensions.
-
{{experimental_inline}} {{jsxref("Operators/Generator_comprehensions", "(for (x of y) y)")}}
-
Generator comprehensions.
-
- -

Comprehensions exist in many programming languages and allow you to quickly assemble a new array based on an existing one, for example.

- -
[for (i of [ 1, 2, 3 ]) i*i ];
-// [ 1, 4, 9 ]
-
-var abc = [ "A", "B", "C" ];
-[for (letter of abc) letter.toLowerCase()];
-// [ "a", "b", "c" ]
- -

Left-hand-side expressions

- -

Left values are the destination of an assignment.

- -

new

- -

You can use the new operator to create an instance of a user-defined object type or of one of the built-in object types. Use new as follows:

- -
var objectName = new objectType([param1, param2, ..., paramN]);
-
- -

super

- -

The super keyword is used to call functions on an object's parent. It is useful with classes to call the parent constructor, for example.

- -
super([arguments]); // calls the parent constructor.
-super.functionOnParent([arguments]);
-
- -

Spread operator

- -

The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected.

- -

Example: Today if you have an array and want to create a new array with the existing one being part of it, the array literal syntax is no longer sufficient and you have to fall back to imperative code, using a combination of push, splice, concat, etc. With spread syntax this becomes much more succinct:

- -
var parts = ['shoulder', 'knees'];
-var lyrics = ['head', ...parts, 'and', 'toes'];
- -

Similarly, the spread operator works with function calls:

- -
function f(x, y, z) { }
-var args = [0, 1, 2];
-f(...args);
- -
{{PreviousNext("Web/JavaScript/Guide/Funktionen", "Web/JavaScript/Guide/Numbers_and_dates")}}
diff --git a/files/de/web/javascript/guide/control_flow_and_error_handling/index.html b/files/de/web/javascript/guide/control_flow_and_error_handling/index.html new file mode 100644 index 0000000000..97dbba8b3e --- /dev/null +++ b/files/de/web/javascript/guide/control_flow_and_error_handling/index.html @@ -0,0 +1,430 @@ +--- +title: Kontrollfluss und Fehlerbehandlung +slug: Web/JavaScript/Guide/Kontrollfluss_und_Fehlerbehandlung +tags: + - Beginner + - Guide + - JavaScript + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Control_flow_and_error_handling +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Grammatik_und_Typen", "Web/JavaScript/Guide/Schleifen_und_Iterationen")}}
+ +

JavaScript unterstützt eine Menge von Anweisungen, speziell um Verlaufs-Anweisungen zu kontrollieren, welches eine großartige Methode ist um Interaktivität in deine Anwendung einzuarbeiten. Dieses Kapitel liefert dir ein Überblick über diese Anweisungen.

+ +

Die JavaScript Referenzen beinhalten umfassende Details über die Anweisungen in diesem Kapitel. Das Semikolon (;) als Zeichen wird genutzt um Anweisungen im JavaScript Code einzuteilen.

+ +

Jeder JavaScript Ausdruck ist auch eine Anweisung. Schau ebenfalls in Ausdrücke und Operatoren, um komplette Informationen über Ausdrücke zu erhalten.

+ +

Block-Anweisungen

+ +

Das einfachste Statement ist das Block-Statement, welches genutzt wird um Anweisungen zu gruppieren. Dieser Block wird von einem Paar geschweiften Klammer umschlossen:

+ +
{
+  statement_1;
+  statement_2;
+  .
+  .
+  .
+  statement_n;
+}
+
+ +

Beispiele

+ +

Block-Statements werden meistens mit Kontrollfluss-Statements genutzt (z. B. if, for, while).

+ +
while (x < 10) {
+  x++;
+}
+
+ +

Hier ist, { x++; } das Block-Statement.

+ +

Wichtig: JavaScript hat vor ECMAScript2015 keine Block-Scopes. Variablen, die in einem Block deklariert werden, gehören zu der Funktion oder dem Skript und das Beschreiben der Variablen führt dazu, dass diese über den Block hinaus verfügbar ist. In anderen Worten, Block-Statements definieren keinen Scope. Alleinstehende Blöcke in JavaScript können komplett andere Ergebnisse erzeugen als in C oder Java. Zum Beispiel:

+ +
var x = 1;
+{
+  var x = 2;
+}
+console.log(x); // outputs 2
+
+ +

Hier wird 2 ausgegeben, weil var x innerhalb des Blocks im gleichen Scope ist wie das var x vor dem Block. In C oder Java hätte der selbe Code 1 ausgegeben.

+ +

Seit ECMAScript2015 sind let und const Variablendeklarationen, die an den Block gebunden sind. Siehe dazu auch die Referenzseiten {{jsxref("Statements/let", "let")}} und {{jsxref("Statements/const", "const")}} an.

+ +

Bedingte Statements

+ +

Ein bedingtes Statement ist eine Menge von Befehlen, die ausgeführt werden, wenn eine Bedingung wahr ist. JavaScript unterstützt zwei bedingte Statements: if...else und switch.

+ +

if...else Anweisungen

+ +

if wird eingesetzt um Statements auszuführen, wenn eine logische Bedingung wahr wird. Mit der optionalen else-Klausel werden Statements ausgeführt, wenn die Bedingung falsch ist. Ein if-Block sieht folgendermaßen aus:

+ +
if (bedingung) {
+  statement_1;
+} else {
+  statement_2;
+}
+ +

Hier kann die Bedingung ein Ausdruck sein, der zu true oder false ausgewertet wird. Siehe Boolean nach, um zu erfahren, was zu true und was zu false ausgewertet wird. Wenn bedingung zu true ausgewertet wird, wird statement_1 ausgeführt. Andernfalls wird statement_2 ausgeführt. statement_1 und statement_2 können beliebige Statements sein, auch weitere if-Statements.

+ +

Man kann zudem Statements mit else if konstruieren, um mehrere Bedingungen sequentiell zu testen:

+ +
if (bedingung_1) {
+  statement_1;
+} else if (bedingung_2) {
+  statement_2;
+} else if (bedingung_n) {
+  statement_n;
+} else {
+  statement_last;
+}
+
+ +

Um mehrere Statements auszuführen, werden diese in Blockstatements gruppiert ({ ... }). Generell ist es guter Stil immer Block-Statements zu benutzen, besonders bei verschachtelten if-Statements.

+ +
if (bedingung) {
+  statement_1_runs_if_condition_is_true;
+  statement_2_runs_if_condition_is_true;
+} else {
+  statement_3_runs_if_condition_is_false;
+  statement_4_runs_if_condition_is_false;
+}
+
+ +

Es ist ratsam, keine einfachen Zuweisungen in Bedingungen zu verwenden, da die Zuordnung mit der Prüfung auf Gleichheit verwechselt werden kann, wenn man über den Code schaut. Verwenden Sie zum Beispiel den folgenden Code nicht:

+ +
if (x = y) {
+  /* statements here */
+}
+
+ +

Wenn eine Zuweisung in einer Bedingung benötigt wird, ist es verbreitet diese in weitere runde Klammeren zu schreiben. Zum Beispiel:

+ +
if ((x = y)) {
+  /* statements here */
+}
+
+ +

Falsy Werte

+ +

Die folgenden Werte werden zu false ausgewertet (auch bekannt als {{Glossary("Falsy")}} Werte):

+ + + +

Alle anderen Werte, auch alle Objekte, werden zu true ausgewertet, wenn sie als Bedingung eingesetzt werden.

+ +

Es ist jedoch etwas verwirrend mit den primitiven boolean Werten true und false und den Werten des {{jsxref("Boolean")}}-Objektes, wie folgendes Beispiel zeigt:

+ +
var b = new Boolean(false);
+if (b)          // Die Bedingung wird zu true ausgewertet.
+if (b == true)  // Die Bedingung wird zu false ausgewertet.
+ +

Beispiel

+ +

Im folgenden Beispiel gibt die Funktion checkData true zurück, wenn die Anzahl der Zeichen in einem Text Objekt drei ist. Andernfalls wird ein Alert angezeigt, und false zurückgegeben.

+ +
function checkData() {
+  if (document.form1.threeChar.value.length == 3) {
+    return true;
+  } else {
+    alert("Enter exactly three characters. " +
+    document.form1.threeChar.value + " is not valid.");
+    return false;
+  }
+}
+
+ +

switch Statement

+ +

Ein switch Statement erlaubt es einen Ausdruck auszuwerten und das Resultat zu einem passenden Fall-Label (case-Label ) zuzuordnen. Wenn ein passendes Fall-Label gefunden wird, werden die zugehörigen Statements ausgeführt. Ein switch Statement sieht wie folgt aus:

+ +
switch (ausdruck) {
+  case label_1:
+    statements_1
+    [break;]
+  case label_2:
+    statements_2
+    [break;]
+    ...
+  default:
+    statements_def
+    [break;]
+}
+
+ +

Das Programm sucht als erstes nach eine case-Klausel mit einem Label, welches mit dem Wert des Ausgewerteten Ausdrucks übereinstimmt und gibt die Kontrolle zu dieser Klausel, was bedeutet, dass die zugehörigen Statements ausgeführt werden. Wenn kein passendes Label gefunden wird, sucht das Programm nach der optionalen default-Klausel und gibt die Kontrolle an diese, was bedeutet, dass die zugehörigen Statements ausgeführt werden. Wenn keine default-Klausel vorhanden ist, wird das switch beendet und das nächste Statement wird ausgeführt. Laut Konventionen ist die default-Klausel die letzte Klausel, das muss aber nicht immer so sein.

+ +

Das optionale break Statement, welches in jeder case-Klausel eingesetzt ist, sorgt daführ, dass nach der Klausel das switch Statement beendet wird und das Programm mit dem nachfolgenden Statement weiter macht. Wenn break weggelassen wird, wird das Programm mit dem nächsten Statement im switch weitermachen, was dazu führt, dass alle nachlogenden case-Klauseln und die optionale default-Klausel mit ausgeführt werden.

+ +

Beispiel

+ +

Im folgenden Beispiel wird der case "Bananas" ausgeführt, wenn fruittype zu "Bananas" ausgewertet wird. Die break Statements bewirken, dass das switch beendet wird und das nach switch stehende Statement ausgeführt wird. Wird break im case "Bananas" weggelassen, so wird der case "Cherries" mit ausgeführt.

+ +
switch (fruittype) {
+  case 'Oranges':
+    console.log('Oranges are $0.59 a pound.');
+    break;
+  case 'Apples':
+    console.log('Apples are $0.32 a pound.');
+    break;
+  case 'Bananas':
+    console.log('Bananas are $0.48 a pound.');
+    break;
+  case 'Cherries':
+    console.log('Cherries are $3.00 a pound.');
+    break;
+  case 'Mangoes':
+    console.log('Mangoes are $0.56 a pound.');
+    break;
+  case 'Papayas':
+    console.log('Mangoes and papayas are $2.79 a pound.');
+    break;
+  default:
+   console.log('Sorry, we are out of ' + fruittype + '.');
+}
+console.log("Is there anything else you'd like?");
+ +

Statements zur Fehler- bzw. Ausnahmebehandlung

+ +

Man kann mit dem throw Statement Fehler werfen (erzeugen) und diese mit dem Einsatz des try...catch Statements auffangen und verarbeiten.

+ + + +

Ausnahmetypen

+ +

Jedes Objekt in JavaScript kann als Fehler bzw. Ausnahme geworfen werden. Nicht alle Fehlerobjekte müssen auf die gleiche Art und Weise erstellt worden sein. Trotz des häufig Einsatzes von Zahlen oder Strings als Ausnahmen ist es deutlich effektiver die speziell für Ausnahmen erstellten Typen zu benutzen:

+ + + +

throw Statement

+ +

Das throw Statement wird benutzt, um eine Exception (Ausnahme / Fehler) zu werfen. Wenn eine Exception geworfen wird, so wird ein Ausdruck spezifiziert, welcher den Wert, welcher geworfen wird, spezifiziert:

+ +
throw ausdruck;
+
+ +

Man kann jeden Ausdruck werfen, nicht nur Ausdrücke eines bestimmten Typs. Der folgende Code wirft mehrere Ausnahmen verschiedenen Typs:

+ +
throw "Error2";   // String type
+throw 42;         // Number type
+throw true;       // Boolean type
+throw {toString: function() { return "I'm an object!"; } };
+
+ +
Notiz: Man kann ein Objekt beim Werfen einer Exception spezifizieren. Im catch Block können die Eigenschaften des Objektes referenziert werden.
+ +
// Erstellt ein Objekt vom Typ UserException
+function UserException (message){
+  this.message=message;
+  this.name="UserException";
+}
+
+// Macht die Konvertierung der Exception in einen schönen String, wenn die Exception
+// als String genutzt werden soll.
+// (z. B. in der Fehlerconsole)
+UserException.prototype.toString = function () {
+  return this.name + ': "' + this.message + '"';
+}
+
+// Erstellt eine Instanz der UserException und wirft diese
+throw new UserException("Value too high");
+ +

try...catch Statement

+ +

Das try...catch Statement markiert einen Block von Statements, welcher versucht wird auszuführen, und einen oder mehrere Blöcke welche auf geworfene Exceptions abfangen. Wenn eine Exception geworfen wird, fängt das try...catch Statements diese ab.

+ +

Das try...catch Statement besteht aus einem try Block, welcher ein oder mehrere Statements enthält, und null oder mehr catch Blöcken, welche Statements spezifizieren, welche eine im try Block geworfene Exception abfangen und behandeln. Das Statement versucht den try Block erfolgreich abzuarbeiten und wenn dieser nicht erfolgreich ist, wird die Kontrolle an den catch Block gegeben. Wenn ein Statement in dem try Block (oder eine im try Block aufgerufene Funktion) eine Exception wirft, wird der Kontrollfluss sofort an den catch Block übergeben. Wenn keine Exception im try Block geworfen wird, wird der catch Block übersprungen. Der optionale finally Block wird nach dem try und nach dem catch Block ausgeführt, bevor das auf das try...catch Statement folgenden Statement ausgeführt wird.

+ +

Das Folgende Beispiel benutzt ein try...catch Statement. Das Beispiel ruft eine Funktion auf, welche einen Monatsnamen aus einen Array zurückgibt, je nachdem, welcher Wert übergeben wurde. Wenn der übergebene Wert keine korrekte Monatsnummer ist (1 - 12), dann wird eine Exception mit dem Wert "InvalidMonthNo" geworfen und die Statements im catch Block setzen die monthName Variable auf unknown.

+ +
function getMonthName (mo) {
+  mo = mo-1; // Justiert Monatsnummer zu Arrayindex (1=Jan, 12=Dec)
+  var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul",
+                "Aug","Sep","Oct","Nov","Dec"];
+  if (months[mo] != null) {
+    return months[mo];
+  } else {
+    throw "InvalidMonthNo"; // throw Schlüsselwort wird hier benutzt
+  }
+}
+
+try { // statements to try
+  monthName = getMonthName(myMonth); // Funktion die Exceptions werfen kann
+}
+catch (e) {
+  monthName = "unknown";
+  logMyErrors(e); // Gibt Exception Objekt weiter für Fehlerbehandlung
+}
+
+ +

Der catch Block

+ +

Man kann einen catch Block einsetzen, um alle Exceptions, die im try Block generiert werden, zu verarbeiten.

+ +
catch (catchID) {
+  statements
+}
+
+ +

Der catch Block spezifiziert einen Variable (catchID im voranstehenden Syntaxbeispiel), welcher den Wert des throw Statements enthält. Man kann über diese Variable Informationen über die geworfene Exception abfragen. JavaScript erstellt diese Variable, wenn der Programmfluss in den catch Block geht. Die Variable existiert nur in dem catch Block. Nach dem beenden des catch Blocks ist die Variable nicht mehr verfügbar.

+ +

Im nächsten Beispeil wird eine Exception geworfen. Wenn die Exception geworfen wird, wird der Programmfluss in den catch Block gegeben.

+ +
try {
+  throw "myException" // Erstellt eine Exception
+}
+catch (e) {
+  // Statements, die die Exception verarbeiten
+  logMyErrors(e) // Verarbeitet Exception Objekt zur Fehlerbehandlung
+}
+
+ +

Der finally Block

+ +

Der finally Block enthält Statements, welche nach dem try und catch Block ausgeführt werden, bevor das Statement nach dem try...catch Statement ausgeführt wird. Der finally Block wird ausgeführt, egal ob eine Exception geworfen wird oder nicht. Wenn eine Exception geworfen wird, wird der finally auch ausgeführt, wenn kein catch die Exception abfängt.

+ +

Man kann den finally Block benutzen, um Skripte fehlertoleranter zu gestalten. Zum Beispiel kann eine Ressource im finally Block geschlossen werden. Das Folgende Beispiel öffnet eine Datei und führt Statements aus, um die Datei zu benutzen (Serverseitiges JavaScript erlaubt Zugriffe auf Dateien). Wenn eine Exception geworfen wird, während die Datei geöffnet ist, sorgt der finally Block dafür, dass die Datei wieder geschlossen wird.

+ +
openMyFile();
+try {
+  writeMyFile(theData); //Das kann Exceptions werfen
+} catch(e) {
+  handleError(e); // Wenn eine Exception geworfen wird, wird sie hier verarbeitet
+} finally {
+  closeMyFile(); // Schließt immer die Ressource
+}
+
+ +

Wenn der finally Block einen Rückgabewert definiert, ist dieser der Rückgabewert des try-catch-finally Prozedur, unabhängig davon, ob return Statements im try und catch Block verwendet werden.

+ +
function f() {
+  try {
+    console.log(0);
+    throw "bogus";
+  } catch(e) {
+    console.log(1);
+    return true; // Dieses return Statement is überflüssig
+                 // weil im finally Block ebenfalls eins vorhanden ist
+    console.log(2); // wird niemals erreicht
+  } finally {
+    console.log(3);
+    return false; // überschreibt früheres return Statements
+    console.log(4); // wird niemals erreicht
+  }
+  // false wird jetzt zurückgegeben
+  console.log(5); // wird niemals erreicht
+}
+f(); // alerts 0, 1, 3; returns false
+
+ +

Das Überschreiben des Rückgabewertes durch den finally Block überschreibt auch geworfene Exceptions, wenn diese im catch geworfen werden.

+ +
function f() {
+  try {
+    throw "bogus";
+  } catch(e) {
+    console.log('caught inner "bogus"');
+    throw e; // Dieses throw Statement is überflüssig
+             // weil im finally Block ein return vorkommt
+  } finally {
+    return false; // Überschreibt das vorherige "throw"
+  }
+  // false wird zurückgegeben
+}
+
+try {
+  f();
+} catch(e) {
+  // Dieser bereich wird nie erreicht, weil
+  // die Exception durch das return im
+  // finally block überschrieben wird.
+  console.log('caught outer "bogus"');
+}
+
+// OUTPUT
+// caught inner "bogus"
+ +

Verschachtelte try...catch Statements

+ +

Man kann mehrere try...catch Statements ineinander verschachteln. Wenn ein inneres try...catch Statements keinen catch Block hat, wird ein äußeres try...catch Statement mit einem catch Block eine Exception auffangen. Mehr Informationen gibt es im Kapitel Verschachtelte try-Blöcke auf der try...catch Seite.

+ +

Nützliche Verwendung des Error Objekts

+ +

Abhängig vom der Art des Fehlers, möchte man die Möglichkeit haben einen Namen und eine Fehlernachricht zu vergeben. 'name' und 'message' Eigenschaften sind generell durch die Klasse Error (z. B. DOMException oder Error) unterstützt. Die 'message' Eigenschaft ist dabei eine String-Repräsentation des Fehlers, so wie sie bei der Konvertierung des Objektes zu einem String benötigt wird.

+ +

Wenn man beim Werfen von eigenen Exceptions die Vorteile dieser Eigenschaften nutzen möchte (wenn zum Beipsiel der catch Block nicht zwischen eigenen und System Exceptions unterscheidet), kann der Konstruktor von Error benutzt werden. Zum Beispiel:

+ +
function doSomethingErrorProne () {
+  if (ourCodeMakesAMistake()) {
+    throw (new Error('The message'));
+  } else {
+    doSomethingToGetAJavascriptError();
+  }
+}
+....
+try {
+  doSomethingErrorProne();
+}
+catch (e) {
+  console.log(e.name); // logs 'Error'
+  console.log(e.message); // logs 'The message' or a JavaScript error message)
+}
+ +

Promises

+ +

Mit ECMAScript 6 hat JavaScript die Unterstützung für {{jsxref("Promise")}} Objekte bekommen, welche zum Steuern von asynchronen Operationen genutzt wird.

+ +

Ein Promise ist in einem der folgenen Status:

+ + + +

+ +

Ein Bild mit XHR laden

+ +

Ein einfaches Beispiel für den Einsatz von Promise und XMLHttpRequest ist das Laden eines Bildes (Siehe MDN GitHub js-examples Repository; man kann es hier auch in Aktion sehen). Jeder Schritt ist Kommentiert und erlaubt es der Architektur des Promise und XHR zu folgen. Hier ist die unkommentierte Version, welche den Promise Ablauf zeigt, zu sehen, so dass man eine Idee davon bekommt.

+ +
function imgLoad(url) {
+  return new Promise(function(resolve, reject) {
+    var request = new XMLHttpRequest();
+    request.open('GET', url);
+    request.responseType = 'blob';
+    request.onload = function() {
+      if (request.status === 200) {
+        resolve(request.response);
+      } else {
+        reject(Error('Image didn\'t load successfully; error code:'
+                     + request.statusText));
+      }
+    };
+    request.onerror = function() {
+      reject(Error('There was a network error.'));
+    };
+    request.send();
+  });
+}
+ +

Für deteiliertere Informationen, kann man sich die {{jsxref("Promise")}} Referenz Seite und den Using Promises Guide anschauen.

+ +
{{PreviousNext("Web/JavaScript/Guide/Grammatik_und_Typen", "Web/JavaScript/Guide/Schleifen_und_Iterationen")}}
diff --git a/files/de/web/javascript/guide/details_of_the_object_model/index.html b/files/de/web/javascript/guide/details_of_the_object_model/index.html new file mode 100644 index 0000000000..4d5e46ac26 --- /dev/null +++ b/files/de/web/javascript/guide/details_of_the_object_model/index.html @@ -0,0 +1,721 @@ +--- +title: Feinheiten des Objektmodells +slug: Web/JavaScript/Guide/Feinheiten_des_Objektmodells +tags: + - Guide + - Intermediate + - JavaScript + - Object + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Details_of_the_Object_Model +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Mit_Objekten_arbeiten", "Web/JavaScript/Guide/Using_promises")}}
+ +

JavaScript ist eine Objektbasierte Programmiersprache, die auf Prototypen, statt auf Klassen basiert. Aufgrund dieser Tatsache ist es u. U. schwieriger zu erkennen, wie in JavaScript Objekthierarchien erstellt werden und die Vererbung von Eigenschaften und deren Werten erfolgt. Dieses Kapitel versucht diese Situation zu klären.

+ +

Dieses Kapitel geht davon aus, dass bereits Erfahrungen mit JavaScript vorhanden sind und man einfache Objekte mit Funktionen schon erstellt hat.

+ +

Klassenbasierte vs. Prototypbasierte Sprachen

+ +

Klassenbasierte, Objektorientierte Sprachen wie Java und C++ bauen auf dem Konzept von Klassen und Instanzen auf.

+ + + +

Eine Prototypbasierte Sprache wie JavaScript hat diese Unterscheidung nicht: es gibt einfach Objekte. Eine Prototypbasierte Sprache hat die Notation eines prototypischen Objektes, ein Objekt welches als Template genutzt wird und die initialen Eigenschaften für ein neues Objekt vorgibt. Jedes Objekt kann seine eigenen Eigenschaften spezifizieren, entweder beim Erstellen oder zur Laufzeit. Zudem kann jedes Objekt als Prototyp für ein anderes Objekt verwendet werden, was es auch dem zweiten Objekt erlaubt seine Eigenschaften mit dem ersten Objekt zu teilen.

+ +

Eine Klasse definieren

+ +

In einer Klassenbasierten Sprache definiert man Klassen in separaten Klassendefinitionen. In diesen Definitionen spezifiziert man spezielle Methoden, Konstruktoren genannt, um eine Instanz der Klasse zu erstellen. Eine Konstruktormethode spezifiziert Initialwerte für die Eigenschaften einer Instanz und kann andere Prozesse während der Erstellungszeit durchführen. Man benutzt den new Operator in Verbindung mit der Konstruktormethode, um Klasseninstanzen zu erstellen.

+ +

JavaScript folgt einem ähnlichen Modell, jedoch hat keine vom Konstruktor getrennte Klassendefinition. Stattdessen definiert man eine Konstruktorfunktion, um ein Objekt mit einer initialen Menge an Eigenschaften und Werten zu erstellen. Jede JavaScript Funktion kann als Konstruktor verwendet werden. Man benutzt den new Operator mit einer Konstruktorfunktion, um ein neues Objekt zu erstellen.

+ +

Unterklassen und Vererbung

+ +

In einer Klassenbasierten Sprache erstellt man eine Hierarchie von Klassen durch die Klassendefinition. In der Klassendefinition kann man spezifizieren, dass die neue Klasse eine Unterklasse der schon existierenden Klassen ist. Die Unterklasse erbt alle Eigenschaften von der Oberklasse und kann neue Eigenschaften hinzufügen oder vererbte verändern. Angenommen die Employee Klasse hat nur die Eigenschaften name und dept und Manager ist eine Unterklasse von Employee welche die Eigenschaft reports hinzufügt. In diesem Fall hat eine Instanz der Manager Klasse alle drei Eigenschaften: name, dept und reports.

+ +

JavaScript implementiert Vererbung so, dass man jedes Prototypobjekt mit jeder Konstruktorfunktion verbinden kann. So kann man das gleiche EmployeeManager Beispiel erstellen, jedoch mit einer leicht anderen Terminologie. Als erstes definiert man die Employee Konstruktorfunktion, welche die Eigenschaften name und dept spezifiziert. Als nächstes definiert man die Manager Konstruktorfunktion, ruft den Employee Konstruktor auf und spezifiziert die reports Eigenschaft. Letztlich weist man ein neues Objekt zu, welches von Employee.prototype stammt und als prototype für die Manager Konstruktorfunktion dient. Dann, wenn man einen neuen Manager erstellt, erbt dieser die Eigenschaften name und dept von dem Employee Objekt.

+ +

Hinzufügen und Entfernen von Eigenschaften

+ +

In Klassenbasierten Sprachen wird eine Klasse typischerweise zur Übersetzungszeit erstellt und Instanzen dieser Klasse werden zur Übersetzungs- oder Laufzeit instantiiert. Man kann die Anzahl oder die Typen von Eigenschaften einer Klasse nicht nach der Definition der Klasse verändern. In JavaScript kann man immer EIgenschaften während der Laufzeit zu Objekten hinzufügen oder von ihnen entfernen. Wenn eine Eigenschaft zu einem Objekt hinzugefügt wird, welches als Prototyp für andere Objekte fungiert, so bekommen die anderen Objekte auch diese neue Eigenschaft.

+ +

Zusammenfassung von Unterschieden

+ +

Die folgende Tabelle gibt eine kurze Zusammenfassung von einigen der Unterschiede. Der Rest des Kapitels beschreibt detailliert den Einsatz von JavaScript Konstruktoren und Prototypen, um eine Objekthierarchie zu erstellen und vergleicht dieses mit der Sprache Java.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Vergleich von Klassbasierten (Java) und Prototypebasierten (JavaScript) Objektsystemen
Klassenbasiert (Java)Prototypbasiert (JavaScript)
Klassen und Instanzen sind verschiedene Dinge.Alle Objekte können von anderen Objekt erben.
Definieren einer Klasse mit einer Klassendefinition; Instantiieren eine Klasse mit Konstruktormethoden.Definieren und Erstellen einer Menge von Objekten mit Konstruktorfunktionen.
Erstellt ein Objekt mit dem new Operator.Genauso.
Konstruiert eine Objekthierarchie mit Klassendefinitionen, um Unterklasse aus existierenden Klassen zu definieren.Konstruiert eine Objekthierarchie, indem ein Objekt als Prototyp mit einer Konstruktorfunktion verbunden werden.
Erbt Eigenschaften entlang der Klassenkette.Erbt Eigenschaften entlang der Prototypenkette.
Klassendefinitionen spezifizieren alle Eigenschaften von allen Klasseninstanzen. Man kann keine Eigenschaften dynamisch zur Laufzeit hinzufügen.Konstruktorfunktionen oder Prototypen spezifizieren eine initiale Menge von Eigenschaften. Man kann Eigenschaften dynamisch zu individuellen Objekten hinzufügen oder entfernen oder zu einer Menge von Objekten.
+ +

Das Mitarbeiter-Beispiel

+ +

Das restliche Kapitel benutzt die Mitarbeiterhierarchie, die in folgender Grafik dargestellt ist.

+ +
+
+

Eine einfache Objekthierarchie mit den folgenden Objekten:

+ +

+
+ +
+
    +
  • Employee (Mitarbeiter) hat die Eigenschafte name (die als Initialwert einen leerer String hat) und dept (Abteilung) (die als Initialwert "general" hat).
  • +
  • Manager basiert auf Employee. Er fügt die Eigenschaft reports (Berichte) hinzu (die als Initialwert ein leeres Array hat und für ein Array von Employees vorgesehen ist).
  • +
  • WorkerBee (Arbeitsbiene) basiert ebenfalls auf Employee. Er fügt die Eigenschaft projects hinzu (die als Initialwert ein leeres Array hat und für ein Array von Strings vorgesehen ist).
  • +
  • SalesPerson (Verkäufer) basiert auf WorkerBee. Er fügt die Eigenschaft quota (Pensum) hinzu (die als Initialwert 100 hat). zudem überschreibt er die dept Eigenschaft mit dem Wert "sales", um anzudeuten, dass alle Verkäufer in der gleichen Abteilung sind.
  • +
  • Engineer (Ingenieur) basiert auf WorkerBee. Er fügt die Eigenschaft machine (Maschine) hinzu (die als Initialwert einen leeren String hat) und überschreibt die Eigenschaft dept mit dem Wert "engineering".
  • +
+
+
+ +

Erstellen der Hierarchie

+ +

Es gibt viele Wege, um angemessene Konstruktorfunktionen für die Mitarbeiterhierarchie zu implementieren. Welchen man auswählt hängt stark davon ab, was in der Anwendung erreicht werden soll.

+ +

Dieser Abschnitt zeigt, wie man eine sehr einfache (und vergleichbar unflexible) Definition benutzen kann, um zu demonstrieren, wie die Vererbung funktioniert. In dieser Definition ist es nicht möglich jeden Eigenschaftswert zu spezifizieren, wenn ein Objekt erstellt wird. Die neu erstellten Objekte bekommen nur die Initialwerte und können später verändert werden.

+ +

In einer echten Anwendung würde man Konstruktoren so definieren, dass man diesen Eigenschaftswerte zur Erstellzeit übergeben kann (siehe Flexiblere Konstruktoren für mehr Informationen). Für den Anfang zeigen diese Definitionen wie die Vererbung funktioniert.

+ +

Die folgenden Java und JavaScript Employee Definitionen sind gleich. Der einzige Unterschied ist, dass in Java für jede Eigenschaft ein Typ definiert sein muss, in JavaScript jedoch nicht (das liegt daran, dass Java eine stark typisierte Sprache ist, während JavaScript eine schwach typisierte Sprache ist).

+ +
+

JavaScript

+ +
function Employee() {
+  this.name = '';
+  this.dept = 'general';
+}
+
+ +


+ Java

+ +
public class Employee {
+   public String name = "";
+   public String dept = "general";
+}
+
+
+ +

Die Manager und WorkerBee Definitionen zeigen die Unterschiede bei der Spezifizierung eines Oberobjektes in der Vererbungskette. In JavaScript fügt man eine Prototypinstanz der Eigenschaft prototype der Konstruktorfunktion hinzu. Man kann dieses zu jedem Zeitpunkt nach der Definition des Konstruktors machen. In Java spezifiziert man die Oberklasse in der Klassendefinition. Man kann die Oberklasse nicht außerhalb der Klassendefinition ändern.

+ +
+

JavaScript

+ +
function Manager() {
+  Employee.call(this);
+  this.reports = [];
+}
+Manager.prototype =
+    Object.create(Employee.prototype);
+
+function WorkerBee() {
+  Employee.call(this);
+  this.projects = [];
+}
+WorkerBee.prototype =
+    Object.create(Employee.prototype);
+
+ +


+ Java

+ +
public class Manager extends Employee {
+   public Employee[] reports =
+       new Employee[0];
+}
+
+
+
+public class WorkerBee extends Employee {
+   public String[] projects = new String[0];
+}
+
+
+
+
+ +

Die Engineer und SalesPerson Definition erstellt Objekte, welche von WorkerBee und somit auch von Employee abstammen. Ein Objekt von diesen Typen hat alle Eigenschaften der vorherigen Objekte in der Vererbungskette. Zudem überschreiben diese Definitionen den Wert der geerbten dept Eigenschaft mit einem neuen Wert für diese Objekte.

+ +
+

JavaScript

+ +
function SalesPerson() {
+   WorkerBee.call(this);
+   this.dept = 'sales';
+   this.quota = 100;
+}
+SalesPerson.prototype =
+    Object.create(WorkerBee.prototype);
+
+function Engineer() {
+   WorkerBee.call(this);
+   this.dept = 'engineering';
+   this.machine = '';
+}
+Engineer.prototype =
+    Object.create(WorkerBee.prototype);
+
+ +


+ Java

+ +
public class SalesPerson extends WorkerBee {
+   public String dept = "sales";
+   public double quota = 100.0;
+}
+
+
+public class Engineer extends WorkerBee {
+   public String dept = "engineering";
+   public String machine = "";
+}
+
+
+
+ +

Mit diesen Definitionen kann man Instanzen dieser Objekte mit ihren Initialwerten und Eigenschaften erstellen. Die nächste Grafik zeigt diese JavaScript Definitionen, um neue Objekte zu erzeugen und die Werte der neuen Objekte.

+ +
+

Hinweis: Der Term Instanz hat eine spezielle technische Bedeutung in Klassenbasierten Sprachen. In diesen Sprachen ist eine Instanz eine individuelle Instanz von einer Klasse und ist fundamental anders als eine Klasse. In JavaScript gibt es diese technische Bedeutung nicht, weil JavaScript nicht zwischen Klassen und Instanzen unterscheidet. Immer wenn über JavaScript Instanzen gesprochen wird, ist das rein informell und bedeutet, dass ein Objekte mit einer Konstruktorfunktion erstellt wurde. So kann man in diesem Beispiel sagen, dass jane eine Instanz von Engineer ist. Ebenso haben die Terme Eltern, Kind, Vorfahre und Nachfahre keine formale Bedeutung in JavaScript; Man kann diese benutzen, um deutlich zu machen wo sich ein Objekt in der Prototypenkette befindet.

+
+ +

Objekte mit der einfachen Definition erstellen

+ +
+

Objekthierarchie

+ +

Die folgende Hierarchie wird mit dem Code auf der rechten Seite erstellt.

+ +

+ +

Individuelle Objekte = Jim, Sally, Mark, Fred, Jane, etc.
+ "Instanzen" erstellt vom Konstruktor

+ +
var jim = new Employee;
+// Parentheses can be omitted if the
+// constructor takes no arguments.
+// jim.name is ''
+// jim.dept is 'general'
+
+var sally = new Manager;
+// sally.name is ''
+// sally.dept is 'general'
+// sally.reports is []
+
+var mark = new WorkerBee;
+// mark.name is ''
+// mark.dept is 'general'
+// mark.projects is []
+
+var fred = new SalesPerson;
+// fred.name is ''
+// fred.dept is 'sales'
+// fred.projects is []
+// fred.quota is 100
+
+var jane = new Engineer;
+// jane.name is ''
+// jane.dept is 'engineering'
+// jane.projects is []
+// jane.machine is ''
+
+
+ +

Objekteigenschaften

+ +

Dieser Abschnitt diskutiert, wie Objekte EIgenschaften von anderen Objekten in der Prototypenkette erben und was passiert, wenn eine Eigenschaft währende der Laufzeit hinzugefügt wird.

+ +

Eigenschaften vererben

+ +

Es wird vorausgesetzt, dass das Objekt mark als WorkerBee mit dem folgenden Statement erstellt wurde:

+ +
var mark = new WorkerBee;
+
+ +

Wenn JavaScript den new Operator sieht, erstellt es ein neues generisches Objekt und setzt implizit den Wert der internen Eigenschaft [[Prototype]] auf den Wert WorkerBee.prototype und setzt die this Referenz in der WorkerBee Konstruktorfunktion auf das neu erstellte Objekt. Die interne [[Prototype]] Eigenschaft legt die Prototypenkette fest, die zum Zurückgeben von Eigenschaftswerten benutzt wird. Sobald diese Eigenschaften gesetzt sind, gibt JavaScript das neue Objekt zurück und das Zuweisungsstatement setzt die Variable mark mit diesem Objekt.

+ +

Dieser Prozess fügt keine Werte in das mark-Objekt (lokale Werte) für Eigenschaften, die mark von der Prototypenkette erbt. Wenn man nach einem Wert einer Eigenschaft fragt, prüft JavaScript erst, ob der Wert in dem Objekt existiert. Wenn dies der Fall ist, wird dieser zurückgegeben. Wenn kein lokaler Wert vorhanden ist, prüft JavaScript die Prototypenkette (über die interne [[Prototype]] Eigenschaft). Wenn ein Objekt in der Prototypenkette einen Wert für die Eigenschaft hat, wird diese zurückgegeben. Wenn keine solche Eigenschaft gefunden wird, geht JavaScript davon aus, dass das Objekt keine solche Eigenschaft hat. Dementsprechend hat das mark Objekt folgende Eigenschaften und Werte:

+ +
mark.name = '';
+mark.dept = 'general';
+mark.projects = [];
+
+ +

Das mark Objekt hat lokale Werte für die name und dept Eigenschaft über den Employee Konstruktor zugewiesen bekommen. Es wurde ein Wert für die Eigenschaft projects vom WorkerBee Konstruktor zugewiesen. Dieses gibt die Vererbung von Eigenschaften und Werten in JavaScript her. Einige Feinheiten dieses Prozesses werden in Eigenschaftsvererbung erneut besuchen behandelt.

+ +

Weil diese Konstruktoren keine instanzspezifischen Werte bereitstellen können, sind diese Informationen generisch. Die Eigenschaftswerte sind die Standardwerte, die bei der Erstellung aller mit WorkerBee erstellten Objekt genutzt werden. Man kann natürlich die Werte jeder Eigenschaft ändern. So kann man spezifische Informationen für mark wie folgt vergeben:

+ +
mark.name = 'Doe, Mark';
+mark.dept = 'admin';
+mark.projects = ['navigator'];
+ +

Eigenschaften hinzufügen

+ +

In JavaScript kann man zu jedem Objekt zur Laufzeit Eigenschaften hinzufügen. Man ist nicht nur auf die unterstützten Eigenschaften der Konstruktorfunktion angewiesen. Um eine Eigenschaft spezifisch zu einem einfachen Objekt hinzuzufügen, kann man diese wie folgt dem Objekt zuweisen:

+ +
mark.bonus = 3000;
+
+ +

Jetzt hat das mark Objekt eine bonus Eigenschaft, aber kein anderer WorkerBee hat diese Eigenschaft.

+ +

Wenn man eine neue Eigenschaft zu einem Objekt hinzufügt, welches als Prototyp für eine Konstruktorfunktion benutzt wird, fügt man die Eigenschaft zu allen Objekten hinzu, die Eigenschaften von diesem Prototypen erben. Zum Beispiel kann man eine specialty Eigenschaft zu allen employees mit dem folgenden Statement hinzufügen:

+ +
Employee.prototype.specialty = 'none';
+
+ +

Nach der Ausführung dieses Statements durch JavaScript, hat das mark Objekt auch die specialty Eigenschaft mit dem Wert "none". Die folgende Grafik zeigt den Effekt des Hinzufügens dieser Eigenschaft zum Employee Prototyp und das Überschreiben des Engineer Prototypen.

+ +


+ Eigenschaften hinzufügen

+ +

Flexiblere Konstruktoren

+ +

Mit den bisher gezeigten Konstruktorfunktionen kann man beim Erstellen einer Instanz keine Eigenschaftswerte angeben. Wie bei Java kann man Konstruktoren Argumente zum Initialisieren von Eigenschaftswerten für Instanzen übergeben. Die folgende Abbildung zeigt eine Möglichkeit, dies zu tun.

+ +


+ Spezifizieren von Eigenschaften in einem Konstruktor, Teil 1

+ +

Die folgende Tabelle zeigt die Java und JavaScript Definitionen für diese Objekte.

+ +
+

JavaScript

+ +

Java

+
+ +
+
function Employee(name, dept) {
+  this.name = name || '';
+  this.dept = dept || 'general';
+}
+
+ +
public class Employee {
+   public String name;
+   public String dept;
+   public Employee () {
+      this("", "general");
+   }
+   public Employee (String name) {
+      this(name, "general");
+   }
+   public Employee (String name, String dept) {
+      this.name = name;
+      this.dept = dept;
+   }
+}
+
+
+ +
+
function WorkerBee(projs) {
+
+ this.projects = projs || [];
+}
+WorkerBee.prototype = new Employee;
+
+ +
public class WorkerBee extends Employee {
+   public String[] projects;
+   public WorkerBee () {
+      this(new String[0]);
+   }
+   public WorkerBee (String[] projs) {
+      projects = projs;
+   }
+}
+
+
+ +
+
+function Engineer(mach) {
+   this.dept = 'engineering';
+   this.machine = mach || '';
+}
+Engineer.prototype = new WorkerBee;
+
+ +
public class Engineer extends WorkerBee {
+   public String machine;
+   public Engineer () {
+      dept = "engineering";
+      machine = "";
+   }
+   public Engineer (String mach) {
+      dept = "engineering";
+      machine = mach;
+   }
+}
+
+
+ +

Diese JavaScript Definitionen benutzen eine spezielle Syntax für das Setzen von Standardwerten:

+ +
this.name = name || '';
+
+ +

Der logische ODER Operator (||) von JavaScript wertet das erste Argument aus. Wenn das Argument zu true konvertiert wird, gibt der Operator dieses zurück. Andernfalls wird der Wert des zweiten Arguments zurückgegeben. Demnach prüft diese Zeile Code, ob name einen nützlichen Wert für die name Eigenschaft hat. Wenn das der Fall ist, wird this.name auf diesen Wert gesetzt. Andernfalls wird this.name auf den leeren String gesetzt. Dieses Kapitel nutzt diese Syntax aus Gründen der Kürze; es kann jedoch auf den ersten Blick verwirrend sein.

+ +
+

Hinweis: Das kann möglicherweise nicht wie erwartet funktionieren, wenn der Konstruktorfunktion Argumente übergeben werden, welche zu false konvertiert werden (wie 0 (null) und der leere String ("")). In diesen Fällen wird der Standardwert benutzt.

+
+ +

Mit dieser Definition, kann man beim Erstellen einer Objektinstanz spezifische Werte für die lokal definierten Eigenschaften benutzen. Man kann das folgende Statement nutzen, um einen neuen Engineer zu erstellen:

+ +
var jane = new Engineer('belau');
+
+ +

Jane's Eigenschaften sind jetzt:

+ +
jane.name == '';
+jane.dept == 'engineering';
+jane.projects == [];
+jane.machine == 'belau';
+
+ +

Zu beachten ist, dass man mit diesen Definitionen keinen Initialwert für vererbte Eigenschaft wie name spezifizieren kann. Wenn man einen Initialwert für vererbe Eigenschaften in JavaScript spezifizieren möchte, muss man mehr Code zum Konstruktor hinzufügen.

+ +

Bisher hat die Konstruktorfunktion ein generisches Objekt erstellt und dann lokale Eigenschaften und Werte für das neue Objekt angegeben. Man kann den Konstruktor weitere Eigenschaften hinzufügen lassen, indem Sie die Konstruktorfunktion für ein Objekt in der Prototypkette direkt aufrufen. Die folgende Abbildung zeigt diese neuen Definitionen.

+ +


+ Spezifizieren von Eigenschaften in einem Konstruktor, Teil 2

+ +

Sehen wir uns eine dieser Definitionen genauer an. Hier ist die neue Definition für den Engineer-Konstruktor:

+ +
function Engineer(name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, 'engineering', projs);
+  this.machine = mach || '';
+}
+
+ +

Angenommen, man erstellt ein neues Engineer-Objekt wie folgt:

+ +
var jane = new Engineer('Doe, Jane', ['navigator', 'javascript'], 'belau');
+
+ +

JavaScript folgt folgenden Schritten:

+ +
    +
  1. Der new Operator erstellt ein generisches Objekt und setzt die __proto__ EIgenschaft auf Engineer.prototype.
  2. +
  3. Der new Operator übergibt das neue Objekt dem Engineer Konstruktor als Wert des this Schlüsselwortes.
  4. +
  5. Der Konstruktor erstellt eine neue Eigenschaft namens base für dieses Objekt und weist dieser den Wert des WorkerBee Konstruktors zu. Das macht den WorkerBee Konstruktor zu einer Methode des Engineer Objektes. Der Name der base Eigenschaft ist nicht festgelegt. Man kann jeden legalen Eigenschaftsnamen nutzen; base erinnert einfach an den Zweck.
  6. +
  7. Der Konstruktor ruft die base Methode auf, übergibt als Argumente zwei der Argumente des Konstruktors ("Doe, Jane" und ["navigator", "javascript"]) und zudem den String "engineering". Der explizite Einsatz von "engineering" im Konstruktor zeigt, dass alle Engineer Objekte den selben Wert für dei geerbte dept Eigenschaft haben und dieser Wert den vererbten Wert von Employee überschreibt.
  8. +
  9. Weil base eine Methode von Engineer ist, weshalb JavaScrip beim Aufruf von base das Schlüsselwort this an das erstellte Objekt aus Schritt 1 bindet. Somit übergibt die WorkerBee Funktion die "Doe, Jane" und "engineering" Argumente zu der Employee Konstruktorfunktion. Nach der Rückgabe der Employee Konstruktorfunktion verwendet die WorkerBee Funktion das restliche Argument, um die projects Eigenschaft zu setzen.
  10. +
  11. Nach der Rückgabe der base Methode initialisiert der Engineer Konstruktor die Objekteigenschaft machine mit "belau".
  12. +
  13. Nach der Rückgabe des Konstruktors weist JavaScript das neue Objekte, der jane Variablen zu.
  14. +
+ +

Man kann denken, dass man, nachdem der WorkerBee-Konstruktor innerhalb des Engineer-Konstruktors aufgerufen wird, die Vererbung für das Engineer-Objekte entsprechend eingerichtet hat. Das ist nicht der Fall. Der Aufruf des WorkerBee Konstruktors stellt sicher, dass ein Engineer Objekt mit den Eigenschaften beginnt, die in allen aufgerufenen Konstruktorfunktionen angegeben sind. Wenn jedoch später eine Eigenschaft zum Employee oder WorkerBee Prototyp hinzugefügt wird, wird diese Eigenschaft nicht von Engineer Objekt geerbt. Nimmt man zum Beispiel folgende Statements an:

+ +
function Engineer(name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, 'engineering', projs);
+  this.machine = mach || '';
+}
+var jane = new Engineer('Doe, Jane', ['navigator', 'javascript'], 'belau');
+Employee.prototype.specialty = 'none';
+
+ +

Das jane Objekt erbt nicht die specialty Eigenschaft. Man muss explizit den Prototypen einstellen, um dynamische Vererbung sicherzustellen. Nimmt man stattdessen folgende Statements an:

+ +
function Engineer(name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, 'engineering', projs);
+  this.machine = mach || '';
+}
+Engineer.prototype = new WorkerBee;
+var jane = new Engineer('Doe, Jane', ['navigator', 'javascript'], 'belau');
+Employee.prototype.specialty = 'none';
+
+ +

Jetzt ist der Wert der specialty Eigenschaft des jane Objektes "none".

+ +

Ein anderer Weg wür Vererbung ist der Einsatz der call() / apply() Methoden. Die folgenden Beispiele sind äquivalent:

+ +
+
function Engineer(name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, 'engineering', projs);
+  this.machine = mach || '';
+}
+
+ +
function Engineer(name, projs, mach) {
+  WorkerBee.call(this, name, 'engineering', projs);
+  this.machine = mach || '';
+}
+
+
+ +

Der Einsatz von javascript call() Methode ergibt ein sauberere Implementierung, weil base nicht mehr benötigt wird.

+ +

Eigenschaftsvererbung erneut besuchen

+ +

Im vorangegangenen Abschnitten wurde beschrieben, wie JavaScript Konstruktoren und Prototypen Hierarchien und Vererbung bereitstellt. Dieser Abschnitt diskutiert einige Feinheiten, die in der vorherigen Diskussion nicht unbedingt ersichtlich waren.

+ +

Lokale versus vererbte Werte

+ +

Wenn man auf eine Objekteigenschaft zugreift, führt JavaScript diese Schritte, wie vorhin in dem Kapitel beschrieben, durch:

+ +
    +
  1. Prüft, ob der Wert lokal existiert. Ist das der Fall, wird er zurückgegeben.
  2. +
  3. Wenn kein lokaler Wert vorhanden ist, wird die Prototypenkette (über die __proto__ Eigenschaft) geprüft.
  4. +
  5. Wenn ein Objekt in der Prototypenkette einen Wert für die spezifizierte Eigenschaft hat, wird dieser zurückgegeben.
  6. +
  7. Wenn keine solche Eigenschaft gefunden wird, hat das Objekt diese Eigenschaft nicht.
  8. +
+ +

Das Resultat dieser Schritte hängt davon ab, wie Dinge im Code definiert sind. Das originale Beispiel hat diese Definition:

+ +
function Employee() {
+  this.name = '';
+  this.dept = 'general';
+}
+
+function WorkerBee() {
+  this.projects = [];
+}
+WorkerBee.prototype = new Employee;
+
+ +

Nimmt man mit diesen Definitionen an, man erstellt amy als eine Instanz von WorkerBee mit folgendem Statement:

+ +
var amy = new WorkerBee;
+
+ +

Das amy Objekt hat eine lokale Eigenschaft, projects. Die Werte der name und dept Eigenschaften sind nicht lokal in amy und werden über die Objekteigenschaft __proto__ von amy erreicht. Deshalb hat amy diese Eigenschaftswerte:

+ +
amy.name == '';
+amy.dept == 'general';
+amy.projects == [];
+
+ +

Nimmt man jetzt an, man ändert den Wert der name Eigenschaft in dem Employee Prototyp:

+ +
Employee.prototype.name = 'Unknown';
+
+ +

Auf den ersten Blick erwartet man, dass der neue Wert an alle Instanzen von Employee propagiert wird. Jedoch ist das falsch.

+ +

Wenn man irgendeine Instanz des Employee Objektes erstellt, bekommt die Instanz einen lokalen Wert für die name Eigenschaft (der leere String). Das bedeutet, wenn man den WorkerBee Prototyp mit einem neuen Employee Objekt einstellt, dass WorkerBee.prototype einen lokalen Wert für die name Eigenschaft hat. Wenn demnach JavaScript nach der name Eigenschaft im amy Objekt sucht (eine Instanz von WorkerBee), wird der lokale Wert der Eigenschaft WorkerBee.prototype gefunden. Demnach wird nicht tiefer in der Kette in Employee.prototype gesucht.

+ +

Wenn man den Wert einer Objekteigenschaft zur Laufzeit ändert möchte und den neuen Wert für alle Nachkommenschaften dieses Objektes haben möchte, kann man die Eigenschaft nicht in der Konstruktorfunktion des Objektes definieren. Stattdessen fügt man sie zu dem Konstruktor assoziierten Prototyp hinzu. Angenommen man ändert zum Beispiel deb vorherigen Code wie folgt:

+ +
function Employee() {
+  this.dept = 'general';    // Note that this.name (a local variable) does not appear here
+}
+Employee.prototype.name = '';    // A single copy
+
+function WorkerBee() {
+  this.projects = [];
+}
+WorkerBee.prototype = new Employee;
+
+var amy = new WorkerBee;
+
+Employee.prototype.name = 'Unknown';
+
+ +

In diesem Fall wird die name Eigenschaft von amy "Unknown".

+ +

Das Beispiel zeigt, dass wenn man Standardwerte für Objekteigenschaften haben möchte und zudem dass diese zur Laufzeit geändert werden können, muss man die Eigenschaft im Konstruktorprototypen setzen und nicht in der Konstruktorfunktion.

+ +

Instanzbeziehungen prüfen

+ +

Das Nachgucken von Eigenschaften in JavaScript prüft erst die eigenen Eigenschaften und wenn die Eigenschaft dort nicht ist die Eigenschaften der speziellen Eigenschaft __proto__. Das setzt sich rekursiv fort; der Prozess wird "nachschlagen in der Prototypenkette" genannt.

+ +

Die spezielle Eigenschaft __proto__ wird beim erstellen des Objektes gesetzt; sie wird auf den Wert der prototype Eigenschaft des Konstruktors gesetzt. Deshalb erstellt der Ausdruck new Foo() ein Objekt mit __proto__ == Foo.prototype. Folglich ändert die Änderung der Foo.prototype Eigenschaft alle Nachschlage Prozesse für alle Objekte, die mit new Foo() erstellt wurden.

+ +

Alle Objekte haben eine __proto__ Objekteigenschaft (außer Object); Alle Funktionen haben eine prototype Objekteigenschaft. So können Objekte über 'Prototypenvererbung' mit anderen Objekten verbunden werden. Man kann auf Vererbung testen, indem __proto__ eines Objekts mit einer prototype Objekt einer Funktion verglichen wird. JavaScript hat dafür eine Kurzschreibweise: der instanceof Operator prüft ein Objekt gegen eine Funktion und gibt true zurück, wenn das Objekt von dem Funktionsprototyp erbt. Zum Beispiel:

+ +
var f = new Foo();
+var isTrue = (f instanceof Foo);
+ +

Für ein detailierteres Beispiel nehmen wir an, dass wir die gleichen Definition wie in Eigenschaften vererben haben. Ein Engineer wird wie folgt erstellt:

+ +
var chris = new Engineer('Pigman, Chris', ['jsd'], 'fiji');
+
+ +

Mit diesem Objekt, sind alle folgenden Statements true:

+ +
chris.__proto__ == Engineer.prototype;
+chris.__proto__.__proto__ == WorkerBee.prototype;
+chris.__proto__.__proto__.__proto__ == Employee.prototype;
+chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype;
+chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
+
+ +

Damit kann man eine instanceOf Funktion wie folgt schreiben:

+ +
function instanceOf(object, constructor) {
+   object = object.__proto__;
+   while (object != null) {
+      if (object == constructor.prototype)
+         return true;
+      if (typeof object == 'xml') {
+        return constructor.prototype == XML.prototype;
+      }
+      object = object.__proto__;
+   }
+   return false;
+}
+
+ +
Hinweis: Die obige Implementierung überprüft den Typ des Objekts gegen "xml", um eine Eigenart der Darstellung von XML-Objekten in neueren JavaScript-Versionen zu umgehen. die wesentlichen Details sind in {{bug(634150)}}, beschrieben.
+ +

Der Einsatz der oben definierten instanceOf Funktion führt bei folgenden Ausdrücken zu true:

+ +
instanceOf(chris, Engineer)
+instanceOf(chris, WorkerBee)
+instanceOf(chris, Employee)
+instanceOf(chris, Object)
+
+ +

Jedoch ist der folgende Ausdruck false:

+ +
instanceOf(chris, SalesPerson)
+
+ +

Globale Informationen in Konstruktoren

+ +

Wenn man einen Konstruktor erstellt, muss man vorsichtig sein, wenn man globale Informationen im Konstruktor einstellt. Nimmt man zum Beispiel an, man möchte eine eindeutige ID, die automatisch für jeden neuen employee zugewiesen wird, kann man die folgende Definition für Employee benutzen:

+ +
var idCounter = 1;
+
+function Employee(name, dept) {
+   this.name = name || '';
+   this.dept = dept || 'general';
+   this.id = idCounter++;
+}
+
+ +

Wenn man mit dieser Definition ein neuen Employee erstellt, weist der Konstruktor die nächste ID in der Sequenz zu und inkrementiert dann den globalen ID-Zähler. Wenn die nächsten Statemants die folgenden sind, so ist victoria.id == 1 und harry.id == 2:

+ +
var victoria = new Employee('Pigbert, Victoria', 'pubs');
+var harry = new Employee('Tschopik, Harry', 'sales');
+
+ +

Auf den ersten Blick ist das super. Jedoch wird idCounter jedes mal, wenn ein Employee erstellt wird, wofür auch immer, inkrementiert. Wenn man eine Employee Hierarchie wie im Kapitel oben gezeigt, so wird der Employee Konstruktor für jedes einstellen des Prototypen aufgerufen. Angenommen man hat den folgenden Code:

+ +
var idCounter = 1;
+
+function Employee(name, dept) {
+   this.name = name || '';
+   this.dept = dept || 'general';
+   this.id = idCounter++;
+}
+
+function Manager(name, dept, reports) {...}
+Manager.prototype = new Employee;
+
+function WorkerBee(name, dept, projs) {...}
+WorkerBee.prototype = new Employee;
+
+function Engineer(name, projs, mach) {...}
+Engineer.prototype = new WorkerBee;
+
+function SalesPerson(name, projs, quota) {...}
+SalesPerson.prototype = new WorkerBee;
+
+var mac = new Engineer('Wood, Mac');
+
+ +

Angenommen die Definitionen lassen hier die base Eigenschaft weg und rufen den Konstruktor oberhalb in der Prototypenkette auf. In diesem Fall, bekommt das mac Objekt die id 5.

+ +

Abhängig von der Anwendung ist es sinnvoll oder auch nicht, dass der Zähler an diesen Stellen extra hochzählt. Wenn man an dem exakten Wert des Zählers interessiert ist, ist eine mögliche Lösung den folgenden Konstruktor zu nutzen:

+ +
function Employee(name, dept) {
+   this.name = name || '';
+   this.dept = dept || 'general';
+   if (name)
+      this.id = idCounter++;
+}
+
+ +

Wenn eine Instanz von Employee erstellt wird, der als Prototyp genutzt wird, übergibt man keine Argumente an den Konstruktor. Benutzt man diese Definition des Konstruktors, wird keine id vergeben und der Zäher nicht aktualisiert, wenn dem Konstruktor keine Argumente übergeben werden. Daraus folgt, dass man einem Employee einen Namen geben muss, damit er eine id erhält. In diesem Beispiel ist mac.id == 1.

+ +

Alternativ kann man WorkerBee eine Kopie des Employee Prototypenobjektes zuweisen:

+ +
WorkerBee.prototype = Object.create(Employee.prototype);
+// instead of WorkerBee.prototype = new Employee
+
+ +

Keine Mehrfachvererbung

+ +

Einige objektorientierte SPrachen erlauben Mehrfachvererbung. Das bedeutet, dass ein Objekt die Eigenschaften und Werte von mehreren Elternobjekte erben kann. JavaScript unterstützt keine Mehrfachvererbung.

+ +

Vererbung von Eigenschafteswerten funktioniert zu JavaScripts Laufzeit durch das Suchen in der Prototypenkette eines Objektes. Weil ein Objekt ein einzigen Prototypen hat, kann JavaScript nicht dynamisch von mehr als einer Prototypenkette erben.

+ +

In JavaScript kann eine Konstruktorfunkton mehrere andere Konstruktorfunktionen in sich aufrufen. Das gibt die Illusion von Mehrfachvererbung. Zum Beispiel die folgenden Statements:

+ +
function Hobbyist(hobby) {
+   this.hobby = hobby || 'scuba';
+}
+
+function Engineer(name, projs, mach, hobby) {
+   this.base1 = WorkerBee;
+   this.base1(name, 'engineering', projs);
+   this.base2 = Hobbyist;
+   this.base2(hobby);
+   this.machine = mach || '';
+}
+Engineer.prototype = new WorkerBee;
+
+var dennis = new Engineer('Doe, Dennis', ['collabra'], 'hugo');
+
+ +

Vorausgesetzt wird, die Definition von WorkerBee früher in diesem Kapitel. In diesem Fall hat das dennis Objekt die folgenden Eigenschaften:

+ +
dennis.name == 'Doe, Dennis';
+dennis.dept == 'engineering';
+dennis.projects == ['collabra'];
+dennis.machine == 'hugo';
+dennis.hobby == 'scuba';
+
+ +

dennis hat also die hobby Eigenschaften des Hobbyist Konstruktors bekommen. Setzt man jetzt noch voraus, dass danach Eigenschaften zum Konstruktorprototypen Hobbyist hinzugefügt werde:

+ +
Hobbyist.prototype.equipment = ['mask', 'fins', 'regulator', 'bcd'];
+
+ +

Das dennis Objekt erbt diese neue Eigenschaft nicht.

+ +
{{PreviousNext("Web/JavaScript/Guide/Mit_Objekten_arbeiten", "Web/JavaScript/Guide/Using_promises")}}
diff --git "a/files/de/web/javascript/guide/einf\303\274hrung/index.html" "b/files/de/web/javascript/guide/einf\303\274hrung/index.html" deleted file mode 100644 index b38cb1b700..0000000000 --- "a/files/de/web/javascript/guide/einf\303\274hrung/index.html" +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: Einführung -slug: Web/JavaScript/Guide/Einführung -tags: - - Beginner - - Guide - - Introduction - - JavaScript - - 'l10n:priority' -translation_of: Web/JavaScript/Guide/Introduction ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammatik_und_Typen")}}
- -

Dieses Kapitel stellt JavaScript vor und behandelt einige grundlegende Konzepte.

- -

Was solltest du bereits wissen

- -

Für diese Einführung solltest du die folgenden Grundkenntnisse besitzen:

- - - -

Wo findest du Informationen zu JavaScript

- -

Die Dokumentation zu JavaScript im MDN umfasst Folgendes:

- - - -

Falls du dich das erste Mal mit JavaScript befasst, beginne einfach mit den Tutorials von Learning the Web [de] und dem JavaScript Guide [de]. Sobald du mit den ersten Grundlagen vertraut bist, kannst du die JavaScript Referenz [de] nutzen, um noch mehr über die einzelnen Methoden, Funktionen und Objekte von JavaScript zu erfahren.

- -

Was ist JavaScript?

- -

JavaScript ist eine plattformübergreifende, objektorientierte Skriptsprache. Es ist eine kompakte und ressourcenschonende Sprache. Innerhalb einer Host-Umgebung kann JavaScript mit den Objekten seiner Umgebung verknüpft werden, um diese programmatisch zu steuern.

- -

JavaScript beinhaltet eine Standardbibliothek von Objekten wie Array, Date, und Math, sowie einen Kern an Sprachelementen wie Operatoren, Kontrollstrukturen und Anweisungen. Der JavaScript-Kern kann für eine Vielzahl von Anwendungsfällen erweitert werden, indem man ihn durch zusätzliche Objekte ergänzt. Beispiele:

- - - -

JavaScript und Java

- -

JavaScript und Java gleichen einander in manchen Aspekten, sind in anderen aber grundlegend verschieden. Die Sprache JavaScript ähnelt Java, verfügt jedoch nicht über Javas statische Typisierung und seine strenge Typprüfung. JavaScript folgt weitgehend der Ausdruckssyntax, den Namenskonventionen und den elementaren Kontrollstrukturen von Java, was der Grund für die Umbenennung von LiveScript in JavaScript gewesen ist.

- -

Im Gegensatz zu Javas durch Deklarationen aufgebautes System, von zur Compile-Zeit verfügbaren Klassen, unterstützt JavaScript ein Laufzeitsystem, das auf einer kleinen Zahl an Datentypen basiert, die numerische und Boolesche Werte sowie Zeichenketten repräsentieren. JavaScript besitzt ein prototypen-basiertes Objektmodell anstatt des verbreiteteren klassenbasierten. Das prototypen-basierte Modell liefert dynamische Vererbung; das bedeutet, was vererbt wird, kann zwischen einzelnen Objekten variieren. JavaScript unterstützt zudem Funktionen ohne spezielle deklarative Anforderungen. Funktionen können Objekt Eigenschaften sein, ausgeführt als schwach typisierte Methoden.

- -

JavaScript ist im Vergleich zu Java eine syntaktisch sehr freie Sprache. Sie müssen nicht alle Variablen, Klassen und Methoden deklarieren. Sie müssen sich nicht damit befassen, ob Methoden öffentlich, privat oder geschützt sind und Sie müssen keine Interfaces implementieren. Variablen, Parameter und Rückgabewerte von Funktionen sind nicht explizit typisiert.

- -

Java ist eine auf schnelle Ausführung und Typsicherheit ausgelegte, klassenbasierte Programmiersprache. Typsicherheit bedeutet, dass Sie zum Beispiel keine Ganzzal in Java in eine Objektreferenz wandeln oder auf geschützten Speicher zugreifen können, indem Sie den Bytecode von Java manipulieren. Javas klassenbasiertes Modell bedeutet, dass Programme ausschließlich aus Klassen und ihren Methoden bestehen. Javas Klassenvererbung und strenge Typisierung erfordern im Allgemeinen eng gekoppelte Objekthierarchien. Wegen dieser Anforderungen ist das Programmieren in Java komplexer als in JavaScript.

- -

Im Gegensatz dazu steht JavaScript in der Tradition einer Reihe kleiner, dynamisch typisierter Sprachen wie HyperTalk und dBase. Diese Skriptsprachen stellen, dank ihrer einfacheren Syntax, spezialisierter eingebauter Funktionalität und minimalen Anforderungen, für die Objektgenerierung Programmierwerkzeuge für einen deutlich breiteren Adressatenkreis zu Verfügung.

- - - - - - - - - - - - - - - - - - - - - - - -
JavaScript im Vergleich zu Java
JavaScriptJava
Objektorientiert. Keine Unterscheidung zwischen Typen von Objekten. Vererbung mittels des Prototypen-Mechanismus, jedes beliebige Objekt kann dynamisch um Eigenschaften und Methoden erweitert werden.Klassenbasiert. Objekte werden in Klassen und Instanzen unterteilt, Vererbung erfolgt vollständig über die Klassenhierarchie. Klassen und Instanzen können keine Eigenschaften und Methoden dynamisch hinzugefügt werden.
Datentypen von Variablen werden nicht deklariert (dynamische Typisierung)Datentypen von Variablen müssen deklariert werden (statische Typisierung)
Kein automatischer Schreibzugriff auf die Festplatte.Kein automatischer Schreibzugriff auf die Festplatte.
- -

Weitere Informationen zu den Unterschieden zwischen JavaScript und Java finden Sie im Kapitel Einzelheiten des Objektmodells.

- -

JavaScript und die ECMAScript-Spezifikation

- -

JavaScript wird durch Ecma International standardisiert — den europäischen Verband zur Standardisierung von Informations- und Telekommunikationssystemen (ECMA war vormals ein Akronym für 'European Computer Manufacturers Association'), um eine standardisierte, internationale Programmiersprache auf der Basis von JavaScript verfügbar zu machen. Diese standardisierte Version von JavaScript, genannt ECMAScript, verhält sich in allen standardkonformen Applikationen identisch. Unternehmen können die offene Sprachdefinition verwenden, um ihre eigene Implementierung von JavaScript zu entwickeln. Der ECMAScript-Standard ist in der Spezifikation ECMA-262 dokumentiert. Unter Neu in JavaScript erfahren Sie mehr über die unterschiedlichen Versionen von JavaScript und den ECMAScript-Spezifikationen.

- -

ECMA-262 ist auch von der ISO (International Organization for Standardization) als ISO-16262 verabschiedet. Sie finden die Spezifikation auch auf der Website von Ecma International. Die Spezifikation von ECMAScript beschreibt nicht das Document Object Model (DOM), welches durch das World Wide Web Consortium (W3C) und der WHATWG (Web Hypertext Application Technology Working Group) standardisiert wird. Das DOM definiert die Art und Weise, in der HTML-Dokumentenobjekte für Ihr Skript sichtbar sind. Um ein besseres Verständnis der verschiedenen bei der Programmierung in JavaScript eingesetzten Technologien zu entwickeln, lesen Sie den Artikel JavaScript Technologieübersicht.

- -

JavaScript-Dokumentation vs. ECMAScript-Spezifikation

- -

Die Spezifikation von ECMAScript besteht aus Anforderungen an eine Implementierung von ECMAScript; sie ist zweckdienlich, falls Sie standardkonforme Spracheigenschaften in Ihrer ECMAScript-Implementierung oder ihrer Laufzeitumgebung (wie SpiderMonkey in Firefox oder v8 in Chrome) realisieren wollen.

- -

Das ECMAScript-Dokument soll nicht den Skriptprogrammierer unterstützen; nutzen Sie für Informationen zum Erstellen von Skripten die JavaScript-Dokumentation.

- -

Die ECMAScript-Spezifikation verwendet Terminologie und Syntax, mit der JavaScript-Programmierer möglicherweise nicht vertraut sind. Obwohl sich die Beschreibung der Sprache in ECMAScript unterscheiden kann, bleibt die Sprache selbst die gleiche. JavaScript unterstützt jede Funktionalität, die in der ECMAScript-Spezifikation genannt wird.

- -

Die JavaScript-Dokumentation beschreibt Aspekte der Sprache in für JavaScript-Programmierer passender Form.

- -

Erste Schritte mit JavaScript

- -

Die ersten Schritte mit JavaScript sind einfach: alles was Sie brauchen, ist einen aktuellen Browser. Diese Einführung nimmt auf einige Spracheigenschaften von JavaScript Bezug, die zur Zeit nur in den jüngsten Versionen von Firefox verfügbar sind, somit wird die Nutzung der aktuellsten Firefox-Version empfohlen.

- -

Es gibt zwei Werkzeuge in Firefox, die zum Experimentieren mit JavaScript nützliche sind: die Web-Konsole and die JavaScript-Umgebung.

- -

Die Web-Konsole

- -

Die Web-Konsole zeigt Ihnen Informationen zur aktuell geladenen Webseite an und beinhaltet zudem eine Kommandozeile, die Sie nutzen können, um JavaScript-Ausdrücke im Kontext der aktuellen Seite auszuführen.

- -

Um die Web-Konsole zu öffnen (Ctrl+Shift+K), wählen Sie "Web-Konsole" im Menü "Entwicklerwerkzeuge", das Sie im Menü von Firefox finden. Die Konsole wird am unteren Rand des Browserfensters angezeigt. Entlang des unteren Randes der Konsole befindet sich die Kommandozeile, in der Sie JavaScript eingeben können; die zugehörige Ausgabe erscheint im darüberliegenden Fensterbereich:

- -

- -

JavaScript-Umgebung (Scratchpad)

- -

Die Web-Konsole eignet sich hervorragend zur Ausführung einzelner Zeilen JavaScript, möchten Sie jedoch mehrere Zeilen ausführen können, ist das nicht besonders komfortabel und Ihren Beispielcode speichern können Sie mit der Web-Konsole auch nicht. Daher ist für komplexere Beispiele die JavaScript-Umgebung die bessere Wahl.

- -

Um die JavaScript-Umgebung zu öffnen (Shift+F4), wählen Sie "JavaScript-Umgebung" aus dem Menü "Entwicklerwerkzeuge", das Sie im Firefox-Menü finden. Die JavaScript-Umgebung öffnet sich in einem eigenen Fenster als Editor, mit dem Sie JavaScript schreiben und im Browser ausführen können. Sie können auch Skripte auf der Festplatte speichern bzw. laden.

- -

- -

Hello world

- -

Beginnen Sie mit dem Programmieren in JavaScript, indem Sie die JavaScript-Umgebung öffnen und Ihr erstes "Hello World"-Programm in JavaScript schreiben:

- -
function greetMe(yourName) {
-  alert("Hello " + yourName);
-}
-
-greetMe("World");
-
- -

Markieren Sie den Quelltext und drücken Sie Ctrl+R, um zu schauen, ob alles funktioniert.

- -

Auf den folgenden Seiten macht Sie diese Einführung mit Syntax und Spracheigenschaften von JavaScript vertraut, sodass Sie bald komplexere Anwendungen schreiben können.

- -

{{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammatik_und_Typen")}}

diff --git a/files/de/web/javascript/guide/expressions_and_operators/index.html b/files/de/web/javascript/guide/expressions_and_operators/index.html new file mode 100644 index 0000000000..7a0e723c6c --- /dev/null +++ b/files/de/web/javascript/guide/expressions_and_operators/index.html @@ -0,0 +1,965 @@ +--- +title: Ausdrücke und Operatoren +slug: Web/JavaScript/Guide/Ausdruecke_und_Operatoren +tags: + - Beginner + - Extensions + - Guide + - JavaScript + - Operatoren + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Expressions_and_Operators +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Funktionen", "Web/JavaScript/Guide/Numbers_and_dates")}}
+ +

Dieses Kapitel beschreibt JavaScript Ausdrücke und Operatoren, Zuweisungsoperatoren, Vergleichsoperatoren, Rechenoperatoren, Bit-Operatoren, Logische Operatoren, Operator zur Zeichenkettenverknüpfung, Bedingte (ternäre) Operatoren und mehr.

+ +

Eine vollständige und detaillierte Liste mit Operatoren und Ausdrücken ist in den Referenzen zu finden.

+ +

Operatoren

+ +

JavaScript besitzt verschiedene Operatortypen. Dieser Abschnitt beschreibt die einzelnen Operatoren und beinhaltet Informationen über die Operator-Prioritäten.

+ + + +

JavaScript verfügt über beides, binäre als auch unäre Operatoren. Zudem existiert ein spezieller ternärer Operator - der Bedingungsoperator. Ein binärer Operator benötigt zwei Operanden, einen vor dem Operator und einen nach dem Operator:

+ +
operand1 operator operand2
+
+ +

Zum Beispiel: 3+4, oder x*y.

+ +

Ein unärer Operator erwartet einen einzelnen Operanden, entweder vor, oder nach dem Operator:

+ +
operator operand
+
+ +

oder

+ +
operand operator
+
+ +

Zum Beispiel: x++, oder ++x.

+ +

Zuweisungsoperatoren

+ +

Ein Zuweisungsoperator weißt seinem linken Operanden einen Wert zu. Dieser Wert basiert auf dem Ergebnis des rechten Operanden. Der einfachste Zuweisungsoperator ist das "Gleich" (=), welches den Wert des rechten Operanden dem linken Operanden zuweist.

+ +

Zum Beispiel: x = y (y wid der Wert von x zugewiesen).

+ +

Es gibt auch zusammengesetzte Zuweisungsoperatoren, diese stellen Abkürzungen für die in der folgenden Tabelle aufgelisteten Operationen dar:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Zusammengesetzte Zuweisungsoperatoren
NameAbgekürzter OperatorAusgeschriebener Operator
Zuweisungx = yx = y
Additionx += yx = x + y
Subraktionx -= yx = x - y
Multiplikationx *= yx = x * y
Divisionx /= yx = x / y
Modulo (Division mit Rest)x %= yx = x % y
Exponentiation assignment {{experimental_inline}}x **= yx = x ** y
Left shift assignmentx <<= yx = x << y
Right shift assignmentx >>= yx = x >> y
Unsigned right shift assignmentx >>>= yx = x >>> y
Bitwise AND assignmentx &= yx = x & y
Bitwise XOR assignmentx ^= yx = x ^ y
Bitwise OR assignmentx |= yx = x | y
+ +

Destrukturierung

+ +

Komplexere Zuweisungen ermöglicht Javascript über die sogenannte Destrukturierung. Diese ermöglicht es, Daten aus Arrays oder Objekten mithilfe einer Syntax zu extrahieren, die die Konstruktion von Array- und Objektliteralen widerspiegelt.

+ +
var foo = ["eins", "zwei", "drei"];
+
+// Ohne Destrukturierung
+var eins   = foo[0];
+var zwei   = foo[1];
+var drei   = foo[2];
+
+// mit Destrukturierung
+var [eins, zwei, drei] = foo;
+ +

Vergleichsoperatoren

+ +

Ein Vergleichsoperator vergleicht seine Operanden und gibt einen logischen Wert zurück, der darauf basiert, ob der Vergleich wahr ist, oder nicht.

+ +

Die Operanden können numerische-, string-, logische- oder Objektwerte sein. Zeichenfolgen werden basierend auf der lexikographischen Standardreihenfolge mit unicodewerten verglichen. Wenn die beiden Operanden nicht vom selben Typ sind, versucht JavaScript in den meisten Fällen, sie in einen geeigneten Typ für den Vergleich zu konvertieren. Dieses Verhalten führt im Allgemeinen dazu, dass die Operanden numerisch verglichen werden. Die einzigen Ausnahmen für die Typumwandlung innerhalb von Vergleichen sind die Operatoren === und !==, die strenge Vergleiche durchführen. Diese Operatoren versuchen nicht, die Operanden in kompatible Typen zu konvertieren, bevor sie die Gleichheit überprüfen.

+ +

Die folgende Tabelle beschreibt die Vergleichsoperatoren in Bezug auf diesen Beispielcode:

+ +
var var1 = 3;
+var var2 = 4;
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Vergleichsoperatoren
OperatorBeschreibungBeispiele, die true zurückgeben
Equal (==)Gibt true zurück, wenn die Operanden gleich sind.3 == var1 +

"3" == var1

+ 3 == '3'
Not equal (!=)Gibt true zurück, wenn die Operanden ungleich sind.var1 != 4
+ var2 != "3"
Strict equal (===)Gibt true zurück, wenn die Operanden gleich sind und auch der Typ übereinstimmt. Weitere Informationen unter {{jsxref("Object.is")}} und sameness in JS.3 === var1
Strict not equal (!==)Gibt true zurück, wenn die Operanden vom selben Typ sind, doch nicht den selben Wert haben, oder wenn sie den selben Wert haben, doch nicht vom selben Typ sind.var1 !== "3"
+ 3 !== '3'
Greater than (>)Gibt true zurück, wenn der linke Operand größer dem rechten Operanden ist.var2 > var1
+ "12" > 2
Greater than or equal (>=)Gibt true zurück, wenn der linke Operand größer als, oder gleich dem linken Operanden ist.var2 >= var1
+ var1 >= 3
Less than (<)Gibt true zurück, wenn der linke Operand kleiner dem rechten Operanden ist.var1 < var2
+ "2" < 12
Less than or equal (<=)Gibt true zurück, wenn der linke Operand kleiner als, oder gleich dem rechten Operanden ist.var1 <= var2
+ var2 <= 5
+ +
+

Note: (=>) ist kein Operator, hiermit werden Arrow functions notiert.

+
+ +

Arithmetische Operatoren (Rechenzeichen)

+ +

Ein arithmetischer Operator nimmt numerische Werte (Literale oder Variablen) als Operanden entgegen und gibt einen einzelnen numerischen Wert zurück. Die arithmetischen Standardoperatoren sind Addition (+), Subtraktion (-), Multiplikation (*) und Division (/). Diese Operatoren funktionieren wie in den meisten anderen Programmiersprachen, wenn sie mit Fließkommazahlen verwendet werden (beachten Sie insbesondere, dass die Division durch Null {{jsxref ("Infinity")}} ergibt).

+ +
1 / 2; // 0.5
+1 / 2 == 1.0 / 2.0; // this is true
+
+ +

Neben den arithmetischen Standardoperatoren (+, -, * /), stellt JavaScript noch weitere Rechenzeichen zur Verfügung. Diese werden in der folgenden Tabelle aufgeführt:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Arithmetische Operatoren
OperatorBeschreibungBeispiel
Remainder (%)Binärer Operator. Gibt den ganzzahligen Rest der Division beider Operanden zurück.12 % 5 gibt 2 zurück.
Increment (++) +

Unärer Operator. Addiert 1 zu seinem Operanden.

+ +

Wenn der Operator vorangestellt wird (++x), gibt er den Wert seines Operanden zurück nachdem 1 addiert wurde; Wenn der Operator nachgestellt wird (x++), gibt er den Wert seines Operanden zurück, bevor 1 addiert wurde.

+
Wenn x gleich 3 ist, setzt ++x x auf 4 und gibt 4 zurück, wobei x++  3 zurückgibt und erst danach x auf 4 setzt.
Decrement (--) +

Unärer Operator. Subtrahiert 1 von seinem Operanden.

+ +

Der Rückgabewert verhält sich analog zum increment Operator.

+
Wenn x gleich 3 ist, setzt --x x auf 2 und gibt 2 zurück, wobei x-- 3 zurückgibt und erst danach, x auf 2 setzt.
Unary negation (-)Unärer Operator. Gibt die Negierung seines Operanden zurück.Wenn x gleich 3 ist, gibt -x -3 zurück.
Unary plus (+)Versucht, den Operanden in eine Zahl umzuwandeln, wenn dies nicht bereits der Fall ist.+"3" gibt 3 zurück.
+ +true gibt 1 zurück.
Exponentiation operator (**) {{experimental_inline}}Calculates the base to the exponent power, that is, baseexponent2 ** 3 gibt 8 zurück.
+ 10 ** -1 gibt 0.1 zurück.
+ +

Bitweise Operatoren

+ +

Ein bitweiser Operator behandelt seine Operanden als eine Menge von 32 Bits (Nullen und Einsen) und nicht als dezimale, hexadezimale oder oktale Zahlen. Zum Beispiel hat die Dezimalzahl Neun eine binäre Darstellung von 1001. Bitweise Operatoren führen ihre Operationen mit solchen binären Darstellungen aus, doch sie geben standardmäßige numerische JavaScript-Werte zurück.

+ +

Die folgende Tabelle fasst die bitweisen Operatoren von JavaScript zusammen.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bitweise Operatoren
OperatorVerwendungBeschreibung
Bitwise ANDa & bReturns a one in each bit position for which the corresponding bits of both operands are ones.
Bitwise ORa | bReturns a zero in each bit position for which the corresponding bits of both operands are zeros.
Bitwise XORa ^ bReturns a zero in each bit position for which the corresponding bits are the same.
+ [Returns a one in each bit position for which the corresponding bits are different.]
Bitwise NOT~ aInverts the bits of its operand.
Left shifta << bShifts a in binary representation b bits to the left, shifting in zeros from the right.
Sign-propagating right shifta >> bShifts a in binary representation b bits to the right, discarding bits shifted off.
Zero-fill right shifta >>> bShifts a in binary representation b bits to the right, discarding bits shifted off, and shifting in zeros from the left.
+ +

Bitweise logische Operatoren

+ +

Konzeptuell arbeiten bitweise logische Operatoren wie folgt:

+ + + +

Zum Beispiel ist die binäre Darstellung der Zahl neun 1001, die binäre Darstellung der Zahl 15 ist 1111. Wenn die bitweisen logischen Operatoren auf diese Zahlen angewendet werden, ergeben sich folgende Ergebnisse:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Beispiele für bitweise Operatoren
AusdruckErgebnisBinäre Darstellung
15 & 991111 & 1001 = 1001
15 | 9151111 | 1001 = 1111
15 ^ 961111 ^ 1001 = 0110
~15-16~00000000...00001111 = 11111111...11110000
~9-10~00000000...00001001 = 11111111...11110110
+ +

Beachte, dass alle 32 Bits invertiert werden, wenn der bitweise NOT Operator benutzt wird. Wenn dabei das höchstwertigste (ganz linke) Bit auf 1 gesetzt wird, entsteht eine negative Zahl. Note that all 32 bits are inverted using the Bitwise NOT operator, and that values with the most significant (left-most) bit set to 1 represent negative numbers (Zweierkomplement). ~x wird also genauso ausgewertet wie -x - 1.

+ +

Bitweise Schiebeoperatoren

+ +

Die bitweisen Schiebeoperatoren erwarten zwei Operanden. Der erste ist der Wert, der geschoben werden soll, der zweite die Anzahl der Bits, um die geschoben werden soll. Die Richtung, in die geschoben wird, wird durch den verwendeten Operator bestimmt.

+ +

Schiebeoperatoren konvertieren ihre Operanden in 32 Bit Integer Zahlen und liefern als Ergebnis einen Wert vom selben Typen wir der linke Operand.

+ +

Die Schiebeoperatoren sind in der folgenden Tabelle aufgelistet.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bitwise shift operators
OperatorDescriptionExample
Left shift
+ (<<)
This operator shifts the first operand the specified number of bits to the left. Excess bits shifted off to the left are discarded. Zero bits are shifted in from the right.9<<2 yields 36, because 1001 shifted 2 bits to the left becomes 100100, which is 36.
Sign-propagating right shift (>>)This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Copies of the leftmost bit are shifted in from the left.9>>2 yields 2, because 1001 shifted 2 bits to the right becomes 10, which is 2. Likewise, -9>>2 yields -3, because the sign is preserved.
Zero-fill right shift (>>>)This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Zero bits are shifted in from the left.19>>>2 yields 4, because 10011 shifted 2 bits to the right becomes 100, which is 4. For non-negative numbers, zero-fill right shift and sign-propagating right shift yield the same result.
+ +

Logische Operatoren

+ +

Logische Operatoren werden normalerweise mit boolesche (logischen) Werten verwendet - hierbei geben sie dann einen booleschen Wert zurück. Die Operatoren && und || geben den Wert von einem der Operatoren zurück, sodass sie im Falle der Verwendung mit einem nicht-booleschen Wert auch einen nicht-booleschen Wert zurückgeben können. Die logischen Operatoren werden in der folgenden Tabelle beschrieben: 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Logische Operatoren
OperatorVerwendungBeschreibung
Logical AND (&&)expr1 && expr2Gibt expr1 zurück, sofern es zu false konvertiert werden kann; ansonsten wird expr2 zurückgegeben. Insofern mit booleschen Werten verwendet, && gibt true zurück, wenn beide Operanden wahr sind; ansonsten false.
Logical OR (||)expr1 || expr2 +

Gibt expr1 zurück, sofern er zu true konvertiert werden kann. Insofern mit booleschen Werten verwendet, gibt der Operator || true zurück, wenn einer von beiden Operanden true ist; wenn beide false sind, wird false zurückgegeben. 

+
Logical NOT (!)!expr +

Gibt false zurück, wenn sein einziger Operand in true konvertiert werden kann; andernfalls gibt er true zurück. 

+
+ +

Beispiele von Ausdrücken, die in false umgewandelt werden können, sind solche, die null, 0, NaN, einen leeren String ("") oder undefined sind. 

+ +

Die folgenden Zeilen zeigen Beispiele des && (logisches UND) Operators.

+ +
var a1 =  true && true;     // t && t returns true
+var a2 =  true && false;    // t && f returns false
+var a3 = false && true;     // f && t returns false
+var a4 = false && (3 == 4); // f && f returns false
+var a5 = "Cat" && "Dog";    // t && t returns Dog
+var a6 = false && "Cat";    // f && t returns false
+var a7 = "Cat" && false;    // t && f returns false
+
+ +

Die folgenden Zeilen zeigen Beispiele des || (logisches ODER) Operators:

+ +
var o1 =  true || true;     // t || t returns true
+var o2 = false || true;     // f || t returns true
+var o3 =  true || false;    // t || f returns true
+var o4 = false || (3 == 4); // f || f returns false
+var o5 = "Cat" || "Dog";    // t || t returns Cat
+var o6 = false || "Cat";    // f || t returns Cat
+var o7 = "Cat" || false;    // t || f returns Cat
+
+ +

Die folgenden Zeilen zeigen Beispiele des ! (logisches NICHT) Operators:

+ +
var n1 = !true;  // !t returns false
+var n2 = !false; // !f returns true
+var n3 = !"Cat"; // !t returns false
+
+ +

Short-circuit-Bewertung 

+ +

Da logische Ausdrücke von links nach rechts bewertet werden, werden sie auf eine mögliche "Abkürzung" (short-circuit) hin gemäß den folgenden Regeln evaluiert:

+ + + +

Die Regeln der Logik garantieren, dass diese Bewertungen immer korrekt sind. Der irgendwas-Operand werden in den o.g. Beispielen hierbei nicht bewertet. 

+ +

String-Operatoren

+ +

In addition to the comparison operators, which can be used on string values, the concatenation operator (+) concatenates two string values together, returning another string that is the union of the two operand strings.

+ +

For example,

+ +
console.log("my " + "string"); // console logs the string "my string".
+ +

The shorthand assignment operator += can also be used to concatenate strings.

+ +

For example,

+ +
var mystring = "alpha";
+mystring += "bet"; // evaluates to "alphabet" and assigns this value to mystring.
+ +

Conditional (ternary) operator

+ +

The conditional operator is the only JavaScript operator that takes three operands. The operator can have one of two values based on a condition. The syntax is:

+ +
condition ? val1 : val2
+
+ +

If condition is true, the operator has the value of val1. Otherwise it has the value of val2. You can use the conditional operator anywhere you would use a standard operator.

+ +

For example,

+ +
var status = (age >= 18) ? "adult" : "minor";
+
+ +

This statement assigns the value "adult" to the variable status if age is eighteen or more. Otherwise, it assigns the value "minor" to status.

+ +

Comma operator

+ +

The comma operator (,) simply evaluates both of its operands and returns the value of the last operand. This operator is primarily used inside a for loop, to allow multiple variables to be updated each time through the loop.

+ +

For example, if a is a 2-dimensional array with 10 elements on a side, the following code uses the comma operator to update two variables at once. The code prints the values of the diagonal elements in the array:

+ +
var x = [0,1,2,3,4,5,6,7,8,9];
+var a = [x, x, x, x, x]
+
+for (var i = 0, j = 9; i <= j; i++, j--)
+  console.log("a[" + i + "][" + j + "]= " + a[i][j]);
+
+ +

Unary operators

+ +

A unary operation is an operation with only one operand.

+ +

delete

+ +

The delete operator deletes an object, an object's property, or an element at a specified index in an array. The syntax is:

+ +
delete objectName;
+delete objectName.property;
+delete objectName[index];
+delete property; // legal only within a with statement
+
+ +

where objectName is the name of an object, property is an existing property, and index is an integer representing the location of an element in an array.

+ +

The fourth form is legal only within a with statement, to delete a property from an object.

+ +

You can use the delete operator to delete variables declared implicitly but not those declared with the var statement.

+ +

If the delete operator succeeds, it sets the property or element to undefined. The delete operator returns true if the operation is possible; it returns false if the operation is not possible.

+ +
x = 42;
+var y = 43;
+myobj = new Number();
+myobj.h = 4;    // create property h
+delete x;       // returns true (can delete if declared implicitly)
+delete y;       // returns false (cannot delete if declared with var)
+delete Math.PI; // returns false (cannot delete predefined properties)
+delete myobj.h; // returns true (can delete user-defined properties)
+delete myobj;   // returns true (can delete if declared implicitly)
+
+ +
Deleting array elements
+ +

When you delete an array element, the array length is not affected. For example, if you delete a[3], a[4] is still a[4] and a[3] is undefined.

+ +

When the delete operator removes an array element, that element is no longer in the array. In the following example, trees[3] is removed with delete. However, trees[3] is still addressable and returns undefined.

+ +
var trees = ["redwood", "bay", "cedar", "oak", "maple"];
+delete trees[3];
+if (3 in trees) {
+  // this does not get executed
+}
+
+ +

If you want an array element to exist but have an undefined value, use the undefined keyword instead of the delete operator. In the following example, trees[3] is assigned the value undefined, but the array element still exists:

+ +
var trees = ["redwood", "bay", "cedar", "oak", "maple"];
+trees[3] = undefined;
+if (3 in trees) {
+  // this gets executed
+}
+
+ +

typeof

+ +

The typeof operator is used in either of the following ways:

+ +
typeof operand
+typeof (operand)
+
+ +

The typeof operator returns a string indicating the type of the unevaluated operand. operand is the string, variable, keyword, or object for which the type is to be returned. The parentheses are optional.

+ +

Suppose you define the following variables:

+ +
var myFun = new Function("5 + 2");
+var shape = "round";
+var size = 1;
+var today = new Date();
+
+ +

The typeof operator returns the following results for these variables:

+ +
typeof myFun;     // returns "function"
+typeof shape;     // returns "string"
+typeof size;      // returns "number"
+typeof today;     // returns "object"
+typeof dontExist; // returns "undefined"
+
+ +

For the keywords true and null, the typeof operator returns the following results:

+ +
typeof true; // returns "boolean"
+typeof null; // returns "object"
+
+ +

For a number or string, the typeof operator returns the following results:

+ +
typeof 62;            // returns "number"
+typeof 'Hello world'; // returns "string"
+
+ +

For property values, the typeof operator returns the type of value the property contains:

+ +
typeof document.lastModified; // returns "string"
+typeof window.length;         // returns "number"
+typeof Math.LN2;              // returns "number"
+
+ +

For methods and functions, the typeof operator returns results as follows:

+ +
typeof blur;        // returns "function"
+typeof eval;        // returns "function"
+typeof parseInt;    // returns "function"
+typeof shape.split; // returns "function"
+
+ +

For predefined objects, the typeof operator returns results as follows:

+ +
typeof Date;     // returns "function"
+typeof Function; // returns "function"
+typeof Math;     // returns "object"
+typeof Option;   // returns "function"
+typeof String;   // returns "function"
+
+ +

void

+ +

The void operator is used in either of the following ways:

+ +
void (expression)
+void expression
+
+ +

The void operator specifies an expression to be evaluated without returning a value. expression is a JavaScript expression to evaluate. The parentheses surrounding the expression are optional, but it is good style to use them.

+ +

You can use the void operator to specify an expression as a hypertext link. The expression is evaluated but is not loaded in place of the current document.

+ +

The following code creates a hypertext link that does nothing when the user clicks it. When the user clicks the link, void(0) evaluates to undefined, which has no effect in JavaScript.

+ +
Click here to do nothing
+
+ +

The following code creates a hypertext link that submits a form when the user clicks it.

+ +

+Click here to submit
+ +

Relational operators

+ +

A relational operator compares its operands and returns a Boolean value based on whether the comparison is true.

+ +

in

+ +

The in operator returns true if the specified property is in the specified object. The syntax is:

+ +
propNameOrNumber in objectName
+
+ +

where propNameOrNumber is a string or numeric expression representing a property name or array index, and objectName is the name of an object.

+ +

The following examples show some uses of the in operator.

+ +
// Arrays
+var trees = ["redwood", "bay", "cedar", "oak", "maple"];
+0 in trees;        // returns true
+3 in trees;        // returns true
+6 in trees;        // returns false
+"bay" in trees;    // returns false (you must specify the index number,
+                   // not the value at that index)
+"length" in trees; // returns true (length is an Array property)
+
+// built-in objects
+"PI" in Math;          // returns true
+var myString = new String("coral");
+"length" in myString;  // returns true
+
+// Custom objects
+var mycar = { make: "Honda", model: "Accord", year: 1998 };
+"make" in mycar;  // returns true
+"model" in mycar; // returns true
+
+ +

instanceof

+ +

The instanceof operator returns true if the specified object is of the specified object type. The syntax is:

+ +
objectName instanceof objectType
+
+ +

where objectName is the name of the object to compare to objectType, and objectType is an object type, such as {{jsxref("Date")}} or {{jsxref("Array")}}.

+ +

Use instanceof when you need to confirm the type of an object at runtime. For example, when catching exceptions, you can branch to different exception-handling code depending on the type of exception thrown.

+ +

For example, the following code uses instanceof to determine whether theDay is a Date object. Because theDay is a Date object, the statements in the if statement execute.

+ +
var theDay = new Date(1995, 12, 17);
+if (theDay instanceof Date) {
+  // statements to execute
+}
+
+ +

Operator precedence

+ +

The precedence of operators determines the order they are applied when evaluating an expression. You can override operator precedence by using parentheses.

+ +

The following table describes the precedence of operators, from highest to lowest.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Operator precedence
Operator typeIndividual operators
member. []
call / create instance() new
negation/increment! ~ - + ++ -- typeof void delete
multiply/divide* / %
addition/subtraction+ -
bitwise shift<< >> >>>
relational< <= > >= in instanceof
equality== != === !==
bitwise-and&
bitwise-xor^
bitwise-or|
logical-and&&
logical-or||
conditional?:
assignment= += -= *= /= %= <<= >>= >>>= &= ^= |=
comma,
+ +

A more detailed version of this table, complete with links to additional details about each operator, may be found in JavaScript Reference.

+ +

Expressions

+ +

An expression is any valid unit of code that resolves to a value.

+ +

Every syntactically valid expression resolves to some value but conceptually, there are two types of expressions: with side effects (for example: those that assign value to a variable) and those that in some sense evaluate and therefore resolve to a value.

+ +

The expression x = 7 is an example of the first type. This expression uses the = operator to assign the value seven to the variable x. The expression itself evaluates to seven.

+ +

The code 3 + 4 is an example of the second expression type. This expression uses the + operator to add three and four together without assigning the result, seven, to a variable.
+
+ JavaScript has the following expression categories:

+ + + +

Primary expressions

+ +

Basic keywords and general expressions in JavaScript.

+ +

this

+ +

Use the this keyword to refer to the current object. In general, this refers to the calling object in a method. Use this either with the dot or the bracket notation:

+ +
this["propertyName"]
+this.propertyName
+
+ +

Suppose a function called validate validates an object's value property, given the object and the high and low values:

+ +
function validate(obj, lowval, hival){
+  if ((obj.value < lowval) || (obj.value > hival))
+    console.log("Invalid Value!");
+}
+
+ +

You could call validate in each form element's onChange event handler, using this to pass it the form element, as in the following example:

+ +

+
+

Enter a number between 18 and 99:

+ +

+ +

Grouping operator

+ +

The grouping operator ( ) controls the precedence of evaluation in expressions. For example, you can override multiplication and division first, then addition and subtraction to evaluate addition first.

+ +
var a = 1;
+var b = 2;
+var c = 3;
+
+// default precedence
+a + b * c     // 7
+// evaluated by default like this
+a + (b * c)   // 7
+
+// now overriding precedence
+// addition before multiplication
+(a + b) * c   // 9
+
+// which is equivalent to
+a * c + b * c // 9
+
+ +

Comprehensions

+ +

Comprehensions are an experimental JavaScript feature, targeted to be included in a future ECMAScript version. There are two versions of comprehensions:

+ +
+
{{experimental_inline}} {{jsxref("Operators/Array_comprehensions", "[for (x of y) x]")}}
+
Array comprehensions.
+
{{experimental_inline}} {{jsxref("Operators/Generator_comprehensions", "(for (x of y) y)")}}
+
Generator comprehensions.
+
+ +

Comprehensions exist in many programming languages and allow you to quickly assemble a new array based on an existing one, for example.

+ +
[for (i of [ 1, 2, 3 ]) i*i ];
+// [ 1, 4, 9 ]
+
+var abc = [ "A", "B", "C" ];
+[for (letter of abc) letter.toLowerCase()];
+// [ "a", "b", "c" ]
+ +

Left-hand-side expressions

+ +

Left values are the destination of an assignment.

+ +

new

+ +

You can use the new operator to create an instance of a user-defined object type or of one of the built-in object types. Use new as follows:

+ +
var objectName = new objectType([param1, param2, ..., paramN]);
+
+ +

super

+ +

The super keyword is used to call functions on an object's parent. It is useful with classes to call the parent constructor, for example.

+ +
super([arguments]); // calls the parent constructor.
+super.functionOnParent([arguments]);
+
+ +

Spread operator

+ +

The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected.

+ +

Example: Today if you have an array and want to create a new array with the existing one being part of it, the array literal syntax is no longer sufficient and you have to fall back to imperative code, using a combination of push, splice, concat, etc. With spread syntax this becomes much more succinct:

+ +
var parts = ['shoulder', 'knees'];
+var lyrics = ['head', ...parts, 'and', 'toes'];
+ +

Similarly, the spread operator works with function calls:

+ +
function f(x, y, z) { }
+var args = [0, 1, 2];
+f(...args);
+ +
{{PreviousNext("Web/JavaScript/Guide/Funktionen", "Web/JavaScript/Guide/Numbers_and_dates")}}
diff --git a/files/de/web/javascript/guide/feinheiten_des_objektmodells/index.html b/files/de/web/javascript/guide/feinheiten_des_objektmodells/index.html deleted file mode 100644 index 4d5e46ac26..0000000000 --- a/files/de/web/javascript/guide/feinheiten_des_objektmodells/index.html +++ /dev/null @@ -1,721 +0,0 @@ ---- -title: Feinheiten des Objektmodells -slug: Web/JavaScript/Guide/Feinheiten_des_Objektmodells -tags: - - Guide - - Intermediate - - JavaScript - - Object - - 'l10n:priority' -translation_of: Web/JavaScript/Guide/Details_of_the_Object_Model ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Mit_Objekten_arbeiten", "Web/JavaScript/Guide/Using_promises")}}
- -

JavaScript ist eine Objektbasierte Programmiersprache, die auf Prototypen, statt auf Klassen basiert. Aufgrund dieser Tatsache ist es u. U. schwieriger zu erkennen, wie in JavaScript Objekthierarchien erstellt werden und die Vererbung von Eigenschaften und deren Werten erfolgt. Dieses Kapitel versucht diese Situation zu klären.

- -

Dieses Kapitel geht davon aus, dass bereits Erfahrungen mit JavaScript vorhanden sind und man einfache Objekte mit Funktionen schon erstellt hat.

- -

Klassenbasierte vs. Prototypbasierte Sprachen

- -

Klassenbasierte, Objektorientierte Sprachen wie Java und C++ bauen auf dem Konzept von Klassen und Instanzen auf.

- - - -

Eine Prototypbasierte Sprache wie JavaScript hat diese Unterscheidung nicht: es gibt einfach Objekte. Eine Prototypbasierte Sprache hat die Notation eines prototypischen Objektes, ein Objekt welches als Template genutzt wird und die initialen Eigenschaften für ein neues Objekt vorgibt. Jedes Objekt kann seine eigenen Eigenschaften spezifizieren, entweder beim Erstellen oder zur Laufzeit. Zudem kann jedes Objekt als Prototyp für ein anderes Objekt verwendet werden, was es auch dem zweiten Objekt erlaubt seine Eigenschaften mit dem ersten Objekt zu teilen.

- -

Eine Klasse definieren

- -

In einer Klassenbasierten Sprache definiert man Klassen in separaten Klassendefinitionen. In diesen Definitionen spezifiziert man spezielle Methoden, Konstruktoren genannt, um eine Instanz der Klasse zu erstellen. Eine Konstruktormethode spezifiziert Initialwerte für die Eigenschaften einer Instanz und kann andere Prozesse während der Erstellungszeit durchführen. Man benutzt den new Operator in Verbindung mit der Konstruktormethode, um Klasseninstanzen zu erstellen.

- -

JavaScript folgt einem ähnlichen Modell, jedoch hat keine vom Konstruktor getrennte Klassendefinition. Stattdessen definiert man eine Konstruktorfunktion, um ein Objekt mit einer initialen Menge an Eigenschaften und Werten zu erstellen. Jede JavaScript Funktion kann als Konstruktor verwendet werden. Man benutzt den new Operator mit einer Konstruktorfunktion, um ein neues Objekt zu erstellen.

- -

Unterklassen und Vererbung

- -

In einer Klassenbasierten Sprache erstellt man eine Hierarchie von Klassen durch die Klassendefinition. In der Klassendefinition kann man spezifizieren, dass die neue Klasse eine Unterklasse der schon existierenden Klassen ist. Die Unterklasse erbt alle Eigenschaften von der Oberklasse und kann neue Eigenschaften hinzufügen oder vererbte verändern. Angenommen die Employee Klasse hat nur die Eigenschaften name und dept und Manager ist eine Unterklasse von Employee welche die Eigenschaft reports hinzufügt. In diesem Fall hat eine Instanz der Manager Klasse alle drei Eigenschaften: name, dept und reports.

- -

JavaScript implementiert Vererbung so, dass man jedes Prototypobjekt mit jeder Konstruktorfunktion verbinden kann. So kann man das gleiche EmployeeManager Beispiel erstellen, jedoch mit einer leicht anderen Terminologie. Als erstes definiert man die Employee Konstruktorfunktion, welche die Eigenschaften name und dept spezifiziert. Als nächstes definiert man die Manager Konstruktorfunktion, ruft den Employee Konstruktor auf und spezifiziert die reports Eigenschaft. Letztlich weist man ein neues Objekt zu, welches von Employee.prototype stammt und als prototype für die Manager Konstruktorfunktion dient. Dann, wenn man einen neuen Manager erstellt, erbt dieser die Eigenschaften name und dept von dem Employee Objekt.

- -

Hinzufügen und Entfernen von Eigenschaften

- -

In Klassenbasierten Sprachen wird eine Klasse typischerweise zur Übersetzungszeit erstellt und Instanzen dieser Klasse werden zur Übersetzungs- oder Laufzeit instantiiert. Man kann die Anzahl oder die Typen von Eigenschaften einer Klasse nicht nach der Definition der Klasse verändern. In JavaScript kann man immer EIgenschaften während der Laufzeit zu Objekten hinzufügen oder von ihnen entfernen. Wenn eine Eigenschaft zu einem Objekt hinzugefügt wird, welches als Prototyp für andere Objekte fungiert, so bekommen die anderen Objekte auch diese neue Eigenschaft.

- -

Zusammenfassung von Unterschieden

- -

Die folgende Tabelle gibt eine kurze Zusammenfassung von einigen der Unterschiede. Der Rest des Kapitels beschreibt detailliert den Einsatz von JavaScript Konstruktoren und Prototypen, um eine Objekthierarchie zu erstellen und vergleicht dieses mit der Sprache Java.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Vergleich von Klassbasierten (Java) und Prototypebasierten (JavaScript) Objektsystemen
Klassenbasiert (Java)Prototypbasiert (JavaScript)
Klassen und Instanzen sind verschiedene Dinge.Alle Objekte können von anderen Objekt erben.
Definieren einer Klasse mit einer Klassendefinition; Instantiieren eine Klasse mit Konstruktormethoden.Definieren und Erstellen einer Menge von Objekten mit Konstruktorfunktionen.
Erstellt ein Objekt mit dem new Operator.Genauso.
Konstruiert eine Objekthierarchie mit Klassendefinitionen, um Unterklasse aus existierenden Klassen zu definieren.Konstruiert eine Objekthierarchie, indem ein Objekt als Prototyp mit einer Konstruktorfunktion verbunden werden.
Erbt Eigenschaften entlang der Klassenkette.Erbt Eigenschaften entlang der Prototypenkette.
Klassendefinitionen spezifizieren alle Eigenschaften von allen Klasseninstanzen. Man kann keine Eigenschaften dynamisch zur Laufzeit hinzufügen.Konstruktorfunktionen oder Prototypen spezifizieren eine initiale Menge von Eigenschaften. Man kann Eigenschaften dynamisch zu individuellen Objekten hinzufügen oder entfernen oder zu einer Menge von Objekten.
- -

Das Mitarbeiter-Beispiel

- -

Das restliche Kapitel benutzt die Mitarbeiterhierarchie, die in folgender Grafik dargestellt ist.

- -
-
-

Eine einfache Objekthierarchie mit den folgenden Objekten:

- -

-
- -
-
    -
  • Employee (Mitarbeiter) hat die Eigenschafte name (die als Initialwert einen leerer String hat) und dept (Abteilung) (die als Initialwert "general" hat).
  • -
  • Manager basiert auf Employee. Er fügt die Eigenschaft reports (Berichte) hinzu (die als Initialwert ein leeres Array hat und für ein Array von Employees vorgesehen ist).
  • -
  • WorkerBee (Arbeitsbiene) basiert ebenfalls auf Employee. Er fügt die Eigenschaft projects hinzu (die als Initialwert ein leeres Array hat und für ein Array von Strings vorgesehen ist).
  • -
  • SalesPerson (Verkäufer) basiert auf WorkerBee. Er fügt die Eigenschaft quota (Pensum) hinzu (die als Initialwert 100 hat). zudem überschreibt er die dept Eigenschaft mit dem Wert "sales", um anzudeuten, dass alle Verkäufer in der gleichen Abteilung sind.
  • -
  • Engineer (Ingenieur) basiert auf WorkerBee. Er fügt die Eigenschaft machine (Maschine) hinzu (die als Initialwert einen leeren String hat) und überschreibt die Eigenschaft dept mit dem Wert "engineering".
  • -
-
-
- -

Erstellen der Hierarchie

- -

Es gibt viele Wege, um angemessene Konstruktorfunktionen für die Mitarbeiterhierarchie zu implementieren. Welchen man auswählt hängt stark davon ab, was in der Anwendung erreicht werden soll.

- -

Dieser Abschnitt zeigt, wie man eine sehr einfache (und vergleichbar unflexible) Definition benutzen kann, um zu demonstrieren, wie die Vererbung funktioniert. In dieser Definition ist es nicht möglich jeden Eigenschaftswert zu spezifizieren, wenn ein Objekt erstellt wird. Die neu erstellten Objekte bekommen nur die Initialwerte und können später verändert werden.

- -

In einer echten Anwendung würde man Konstruktoren so definieren, dass man diesen Eigenschaftswerte zur Erstellzeit übergeben kann (siehe Flexiblere Konstruktoren für mehr Informationen). Für den Anfang zeigen diese Definitionen wie die Vererbung funktioniert.

- -

Die folgenden Java und JavaScript Employee Definitionen sind gleich. Der einzige Unterschied ist, dass in Java für jede Eigenschaft ein Typ definiert sein muss, in JavaScript jedoch nicht (das liegt daran, dass Java eine stark typisierte Sprache ist, während JavaScript eine schwach typisierte Sprache ist).

- -
-

JavaScript

- -
function Employee() {
-  this.name = '';
-  this.dept = 'general';
-}
-
- -


- Java

- -
public class Employee {
-   public String name = "";
-   public String dept = "general";
-}
-
-
- -

Die Manager und WorkerBee Definitionen zeigen die Unterschiede bei der Spezifizierung eines Oberobjektes in der Vererbungskette. In JavaScript fügt man eine Prototypinstanz der Eigenschaft prototype der Konstruktorfunktion hinzu. Man kann dieses zu jedem Zeitpunkt nach der Definition des Konstruktors machen. In Java spezifiziert man die Oberklasse in der Klassendefinition. Man kann die Oberklasse nicht außerhalb der Klassendefinition ändern.

- -
-

JavaScript

- -
function Manager() {
-  Employee.call(this);
-  this.reports = [];
-}
-Manager.prototype =
-    Object.create(Employee.prototype);
-
-function WorkerBee() {
-  Employee.call(this);
-  this.projects = [];
-}
-WorkerBee.prototype =
-    Object.create(Employee.prototype);
-
- -


- Java

- -
public class Manager extends Employee {
-   public Employee[] reports =
-       new Employee[0];
-}
-
-
-
-public class WorkerBee extends Employee {
-   public String[] projects = new String[0];
-}
-
-
-
-
- -

Die Engineer und SalesPerson Definition erstellt Objekte, welche von WorkerBee und somit auch von Employee abstammen. Ein Objekt von diesen Typen hat alle Eigenschaften der vorherigen Objekte in der Vererbungskette. Zudem überschreiben diese Definitionen den Wert der geerbten dept Eigenschaft mit einem neuen Wert für diese Objekte.

- -
-

JavaScript

- -
function SalesPerson() {
-   WorkerBee.call(this);
-   this.dept = 'sales';
-   this.quota = 100;
-}
-SalesPerson.prototype =
-    Object.create(WorkerBee.prototype);
-
-function Engineer() {
-   WorkerBee.call(this);
-   this.dept = 'engineering';
-   this.machine = '';
-}
-Engineer.prototype =
-    Object.create(WorkerBee.prototype);
-
- -


- Java

- -
public class SalesPerson extends WorkerBee {
-   public String dept = "sales";
-   public double quota = 100.0;
-}
-
-
-public class Engineer extends WorkerBee {
-   public String dept = "engineering";
-   public String machine = "";
-}
-
-
-
- -

Mit diesen Definitionen kann man Instanzen dieser Objekte mit ihren Initialwerten und Eigenschaften erstellen. Die nächste Grafik zeigt diese JavaScript Definitionen, um neue Objekte zu erzeugen und die Werte der neuen Objekte.

- -
-

Hinweis: Der Term Instanz hat eine spezielle technische Bedeutung in Klassenbasierten Sprachen. In diesen Sprachen ist eine Instanz eine individuelle Instanz von einer Klasse und ist fundamental anders als eine Klasse. In JavaScript gibt es diese technische Bedeutung nicht, weil JavaScript nicht zwischen Klassen und Instanzen unterscheidet. Immer wenn über JavaScript Instanzen gesprochen wird, ist das rein informell und bedeutet, dass ein Objekte mit einer Konstruktorfunktion erstellt wurde. So kann man in diesem Beispiel sagen, dass jane eine Instanz von Engineer ist. Ebenso haben die Terme Eltern, Kind, Vorfahre und Nachfahre keine formale Bedeutung in JavaScript; Man kann diese benutzen, um deutlich zu machen wo sich ein Objekt in der Prototypenkette befindet.

-
- -

Objekte mit der einfachen Definition erstellen

- -
-

Objekthierarchie

- -

Die folgende Hierarchie wird mit dem Code auf der rechten Seite erstellt.

- -

- -

Individuelle Objekte = Jim, Sally, Mark, Fred, Jane, etc.
- "Instanzen" erstellt vom Konstruktor

- -
var jim = new Employee;
-// Parentheses can be omitted if the
-// constructor takes no arguments.
-// jim.name is ''
-// jim.dept is 'general'
-
-var sally = new Manager;
-// sally.name is ''
-// sally.dept is 'general'
-// sally.reports is []
-
-var mark = new WorkerBee;
-// mark.name is ''
-// mark.dept is 'general'
-// mark.projects is []
-
-var fred = new SalesPerson;
-// fred.name is ''
-// fred.dept is 'sales'
-// fred.projects is []
-// fred.quota is 100
-
-var jane = new Engineer;
-// jane.name is ''
-// jane.dept is 'engineering'
-// jane.projects is []
-// jane.machine is ''
-
-
- -

Objekteigenschaften

- -

Dieser Abschnitt diskutiert, wie Objekte EIgenschaften von anderen Objekten in der Prototypenkette erben und was passiert, wenn eine Eigenschaft währende der Laufzeit hinzugefügt wird.

- -

Eigenschaften vererben

- -

Es wird vorausgesetzt, dass das Objekt mark als WorkerBee mit dem folgenden Statement erstellt wurde:

- -
var mark = new WorkerBee;
-
- -

Wenn JavaScript den new Operator sieht, erstellt es ein neues generisches Objekt und setzt implizit den Wert der internen Eigenschaft [[Prototype]] auf den Wert WorkerBee.prototype und setzt die this Referenz in der WorkerBee Konstruktorfunktion auf das neu erstellte Objekt. Die interne [[Prototype]] Eigenschaft legt die Prototypenkette fest, die zum Zurückgeben von Eigenschaftswerten benutzt wird. Sobald diese Eigenschaften gesetzt sind, gibt JavaScript das neue Objekt zurück und das Zuweisungsstatement setzt die Variable mark mit diesem Objekt.

- -

Dieser Prozess fügt keine Werte in das mark-Objekt (lokale Werte) für Eigenschaften, die mark von der Prototypenkette erbt. Wenn man nach einem Wert einer Eigenschaft fragt, prüft JavaScript erst, ob der Wert in dem Objekt existiert. Wenn dies der Fall ist, wird dieser zurückgegeben. Wenn kein lokaler Wert vorhanden ist, prüft JavaScript die Prototypenkette (über die interne [[Prototype]] Eigenschaft). Wenn ein Objekt in der Prototypenkette einen Wert für die Eigenschaft hat, wird diese zurückgegeben. Wenn keine solche Eigenschaft gefunden wird, geht JavaScript davon aus, dass das Objekt keine solche Eigenschaft hat. Dementsprechend hat das mark Objekt folgende Eigenschaften und Werte:

- -
mark.name = '';
-mark.dept = 'general';
-mark.projects = [];
-
- -

Das mark Objekt hat lokale Werte für die name und dept Eigenschaft über den Employee Konstruktor zugewiesen bekommen. Es wurde ein Wert für die Eigenschaft projects vom WorkerBee Konstruktor zugewiesen. Dieses gibt die Vererbung von Eigenschaften und Werten in JavaScript her. Einige Feinheiten dieses Prozesses werden in Eigenschaftsvererbung erneut besuchen behandelt.

- -

Weil diese Konstruktoren keine instanzspezifischen Werte bereitstellen können, sind diese Informationen generisch. Die Eigenschaftswerte sind die Standardwerte, die bei der Erstellung aller mit WorkerBee erstellten Objekt genutzt werden. Man kann natürlich die Werte jeder Eigenschaft ändern. So kann man spezifische Informationen für mark wie folgt vergeben:

- -
mark.name = 'Doe, Mark';
-mark.dept = 'admin';
-mark.projects = ['navigator'];
- -

Eigenschaften hinzufügen

- -

In JavaScript kann man zu jedem Objekt zur Laufzeit Eigenschaften hinzufügen. Man ist nicht nur auf die unterstützten Eigenschaften der Konstruktorfunktion angewiesen. Um eine Eigenschaft spezifisch zu einem einfachen Objekt hinzuzufügen, kann man diese wie folgt dem Objekt zuweisen:

- -
mark.bonus = 3000;
-
- -

Jetzt hat das mark Objekt eine bonus Eigenschaft, aber kein anderer WorkerBee hat diese Eigenschaft.

- -

Wenn man eine neue Eigenschaft zu einem Objekt hinzufügt, welches als Prototyp für eine Konstruktorfunktion benutzt wird, fügt man die Eigenschaft zu allen Objekten hinzu, die Eigenschaften von diesem Prototypen erben. Zum Beispiel kann man eine specialty Eigenschaft zu allen employees mit dem folgenden Statement hinzufügen:

- -
Employee.prototype.specialty = 'none';
-
- -

Nach der Ausführung dieses Statements durch JavaScript, hat das mark Objekt auch die specialty Eigenschaft mit dem Wert "none". Die folgende Grafik zeigt den Effekt des Hinzufügens dieser Eigenschaft zum Employee Prototyp und das Überschreiben des Engineer Prototypen.

- -


- Eigenschaften hinzufügen

- -

Flexiblere Konstruktoren

- -

Mit den bisher gezeigten Konstruktorfunktionen kann man beim Erstellen einer Instanz keine Eigenschaftswerte angeben. Wie bei Java kann man Konstruktoren Argumente zum Initialisieren von Eigenschaftswerten für Instanzen übergeben. Die folgende Abbildung zeigt eine Möglichkeit, dies zu tun.

- -


- Spezifizieren von Eigenschaften in einem Konstruktor, Teil 1

- -

Die folgende Tabelle zeigt die Java und JavaScript Definitionen für diese Objekte.

- -
-

JavaScript

- -

Java

-
- -
-
function Employee(name, dept) {
-  this.name = name || '';
-  this.dept = dept || 'general';
-}
-
- -
public class Employee {
-   public String name;
-   public String dept;
-   public Employee () {
-      this("", "general");
-   }
-   public Employee (String name) {
-      this(name, "general");
-   }
-   public Employee (String name, String dept) {
-      this.name = name;
-      this.dept = dept;
-   }
-}
-
-
- -
-
function WorkerBee(projs) {
-
- this.projects = projs || [];
-}
-WorkerBee.prototype = new Employee;
-
- -
public class WorkerBee extends Employee {
-   public String[] projects;
-   public WorkerBee () {
-      this(new String[0]);
-   }
-   public WorkerBee (String[] projs) {
-      projects = projs;
-   }
-}
-
-
- -
-
-function Engineer(mach) {
-   this.dept = 'engineering';
-   this.machine = mach || '';
-}
-Engineer.prototype = new WorkerBee;
-
- -
public class Engineer extends WorkerBee {
-   public String machine;
-   public Engineer () {
-      dept = "engineering";
-      machine = "";
-   }
-   public Engineer (String mach) {
-      dept = "engineering";
-      machine = mach;
-   }
-}
-
-
- -

Diese JavaScript Definitionen benutzen eine spezielle Syntax für das Setzen von Standardwerten:

- -
this.name = name || '';
-
- -

Der logische ODER Operator (||) von JavaScript wertet das erste Argument aus. Wenn das Argument zu true konvertiert wird, gibt der Operator dieses zurück. Andernfalls wird der Wert des zweiten Arguments zurückgegeben. Demnach prüft diese Zeile Code, ob name einen nützlichen Wert für die name Eigenschaft hat. Wenn das der Fall ist, wird this.name auf diesen Wert gesetzt. Andernfalls wird this.name auf den leeren String gesetzt. Dieses Kapitel nutzt diese Syntax aus Gründen der Kürze; es kann jedoch auf den ersten Blick verwirrend sein.

- -
-

Hinweis: Das kann möglicherweise nicht wie erwartet funktionieren, wenn der Konstruktorfunktion Argumente übergeben werden, welche zu false konvertiert werden (wie 0 (null) und der leere String ("")). In diesen Fällen wird der Standardwert benutzt.

-
- -

Mit dieser Definition, kann man beim Erstellen einer Objektinstanz spezifische Werte für die lokal definierten Eigenschaften benutzen. Man kann das folgende Statement nutzen, um einen neuen Engineer zu erstellen:

- -
var jane = new Engineer('belau');
-
- -

Jane's Eigenschaften sind jetzt:

- -
jane.name == '';
-jane.dept == 'engineering';
-jane.projects == [];
-jane.machine == 'belau';
-
- -

Zu beachten ist, dass man mit diesen Definitionen keinen Initialwert für vererbte Eigenschaft wie name spezifizieren kann. Wenn man einen Initialwert für vererbe Eigenschaften in JavaScript spezifizieren möchte, muss man mehr Code zum Konstruktor hinzufügen.

- -

Bisher hat die Konstruktorfunktion ein generisches Objekt erstellt und dann lokale Eigenschaften und Werte für das neue Objekt angegeben. Man kann den Konstruktor weitere Eigenschaften hinzufügen lassen, indem Sie die Konstruktorfunktion für ein Objekt in der Prototypkette direkt aufrufen. Die folgende Abbildung zeigt diese neuen Definitionen.

- -


- Spezifizieren von Eigenschaften in einem Konstruktor, Teil 2

- -

Sehen wir uns eine dieser Definitionen genauer an. Hier ist die neue Definition für den Engineer-Konstruktor:

- -
function Engineer(name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, 'engineering', projs);
-  this.machine = mach || '';
-}
-
- -

Angenommen, man erstellt ein neues Engineer-Objekt wie folgt:

- -
var jane = new Engineer('Doe, Jane', ['navigator', 'javascript'], 'belau');
-
- -

JavaScript folgt folgenden Schritten:

- -
    -
  1. Der new Operator erstellt ein generisches Objekt und setzt die __proto__ EIgenschaft auf Engineer.prototype.
  2. -
  3. Der new Operator übergibt das neue Objekt dem Engineer Konstruktor als Wert des this Schlüsselwortes.
  4. -
  5. Der Konstruktor erstellt eine neue Eigenschaft namens base für dieses Objekt und weist dieser den Wert des WorkerBee Konstruktors zu. Das macht den WorkerBee Konstruktor zu einer Methode des Engineer Objektes. Der Name der base Eigenschaft ist nicht festgelegt. Man kann jeden legalen Eigenschaftsnamen nutzen; base erinnert einfach an den Zweck.
  6. -
  7. Der Konstruktor ruft die base Methode auf, übergibt als Argumente zwei der Argumente des Konstruktors ("Doe, Jane" und ["navigator", "javascript"]) und zudem den String "engineering". Der explizite Einsatz von "engineering" im Konstruktor zeigt, dass alle Engineer Objekte den selben Wert für dei geerbte dept Eigenschaft haben und dieser Wert den vererbten Wert von Employee überschreibt.
  8. -
  9. Weil base eine Methode von Engineer ist, weshalb JavaScrip beim Aufruf von base das Schlüsselwort this an das erstellte Objekt aus Schritt 1 bindet. Somit übergibt die WorkerBee Funktion die "Doe, Jane" und "engineering" Argumente zu der Employee Konstruktorfunktion. Nach der Rückgabe der Employee Konstruktorfunktion verwendet die WorkerBee Funktion das restliche Argument, um die projects Eigenschaft zu setzen.
  10. -
  11. Nach der Rückgabe der base Methode initialisiert der Engineer Konstruktor die Objekteigenschaft machine mit "belau".
  12. -
  13. Nach der Rückgabe des Konstruktors weist JavaScript das neue Objekte, der jane Variablen zu.
  14. -
- -

Man kann denken, dass man, nachdem der WorkerBee-Konstruktor innerhalb des Engineer-Konstruktors aufgerufen wird, die Vererbung für das Engineer-Objekte entsprechend eingerichtet hat. Das ist nicht der Fall. Der Aufruf des WorkerBee Konstruktors stellt sicher, dass ein Engineer Objekt mit den Eigenschaften beginnt, die in allen aufgerufenen Konstruktorfunktionen angegeben sind. Wenn jedoch später eine Eigenschaft zum Employee oder WorkerBee Prototyp hinzugefügt wird, wird diese Eigenschaft nicht von Engineer Objekt geerbt. Nimmt man zum Beispiel folgende Statements an:

- -
function Engineer(name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, 'engineering', projs);
-  this.machine = mach || '';
-}
-var jane = new Engineer('Doe, Jane', ['navigator', 'javascript'], 'belau');
-Employee.prototype.specialty = 'none';
-
- -

Das jane Objekt erbt nicht die specialty Eigenschaft. Man muss explizit den Prototypen einstellen, um dynamische Vererbung sicherzustellen. Nimmt man stattdessen folgende Statements an:

- -
function Engineer(name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, 'engineering', projs);
-  this.machine = mach || '';
-}
-Engineer.prototype = new WorkerBee;
-var jane = new Engineer('Doe, Jane', ['navigator', 'javascript'], 'belau');
-Employee.prototype.specialty = 'none';
-
- -

Jetzt ist der Wert der specialty Eigenschaft des jane Objektes "none".

- -

Ein anderer Weg wür Vererbung ist der Einsatz der call() / apply() Methoden. Die folgenden Beispiele sind äquivalent:

- -
-
function Engineer(name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, 'engineering', projs);
-  this.machine = mach || '';
-}
-
- -
function Engineer(name, projs, mach) {
-  WorkerBee.call(this, name, 'engineering', projs);
-  this.machine = mach || '';
-}
-
-
- -

Der Einsatz von javascript call() Methode ergibt ein sauberere Implementierung, weil base nicht mehr benötigt wird.

- -

Eigenschaftsvererbung erneut besuchen

- -

Im vorangegangenen Abschnitten wurde beschrieben, wie JavaScript Konstruktoren und Prototypen Hierarchien und Vererbung bereitstellt. Dieser Abschnitt diskutiert einige Feinheiten, die in der vorherigen Diskussion nicht unbedingt ersichtlich waren.

- -

Lokale versus vererbte Werte

- -

Wenn man auf eine Objekteigenschaft zugreift, führt JavaScript diese Schritte, wie vorhin in dem Kapitel beschrieben, durch:

- -
    -
  1. Prüft, ob der Wert lokal existiert. Ist das der Fall, wird er zurückgegeben.
  2. -
  3. Wenn kein lokaler Wert vorhanden ist, wird die Prototypenkette (über die __proto__ Eigenschaft) geprüft.
  4. -
  5. Wenn ein Objekt in der Prototypenkette einen Wert für die spezifizierte Eigenschaft hat, wird dieser zurückgegeben.
  6. -
  7. Wenn keine solche Eigenschaft gefunden wird, hat das Objekt diese Eigenschaft nicht.
  8. -
- -

Das Resultat dieser Schritte hängt davon ab, wie Dinge im Code definiert sind. Das originale Beispiel hat diese Definition:

- -
function Employee() {
-  this.name = '';
-  this.dept = 'general';
-}
-
-function WorkerBee() {
-  this.projects = [];
-}
-WorkerBee.prototype = new Employee;
-
- -

Nimmt man mit diesen Definitionen an, man erstellt amy als eine Instanz von WorkerBee mit folgendem Statement:

- -
var amy = new WorkerBee;
-
- -

Das amy Objekt hat eine lokale Eigenschaft, projects. Die Werte der name und dept Eigenschaften sind nicht lokal in amy und werden über die Objekteigenschaft __proto__ von amy erreicht. Deshalb hat amy diese Eigenschaftswerte:

- -
amy.name == '';
-amy.dept == 'general';
-amy.projects == [];
-
- -

Nimmt man jetzt an, man ändert den Wert der name Eigenschaft in dem Employee Prototyp:

- -
Employee.prototype.name = 'Unknown';
-
- -

Auf den ersten Blick erwartet man, dass der neue Wert an alle Instanzen von Employee propagiert wird. Jedoch ist das falsch.

- -

Wenn man irgendeine Instanz des Employee Objektes erstellt, bekommt die Instanz einen lokalen Wert für die name Eigenschaft (der leere String). Das bedeutet, wenn man den WorkerBee Prototyp mit einem neuen Employee Objekt einstellt, dass WorkerBee.prototype einen lokalen Wert für die name Eigenschaft hat. Wenn demnach JavaScript nach der name Eigenschaft im amy Objekt sucht (eine Instanz von WorkerBee), wird der lokale Wert der Eigenschaft WorkerBee.prototype gefunden. Demnach wird nicht tiefer in der Kette in Employee.prototype gesucht.

- -

Wenn man den Wert einer Objekteigenschaft zur Laufzeit ändert möchte und den neuen Wert für alle Nachkommenschaften dieses Objektes haben möchte, kann man die Eigenschaft nicht in der Konstruktorfunktion des Objektes definieren. Stattdessen fügt man sie zu dem Konstruktor assoziierten Prototyp hinzu. Angenommen man ändert zum Beispiel deb vorherigen Code wie folgt:

- -
function Employee() {
-  this.dept = 'general';    // Note that this.name (a local variable) does not appear here
-}
-Employee.prototype.name = '';    // A single copy
-
-function WorkerBee() {
-  this.projects = [];
-}
-WorkerBee.prototype = new Employee;
-
-var amy = new WorkerBee;
-
-Employee.prototype.name = 'Unknown';
-
- -

In diesem Fall wird die name Eigenschaft von amy "Unknown".

- -

Das Beispiel zeigt, dass wenn man Standardwerte für Objekteigenschaften haben möchte und zudem dass diese zur Laufzeit geändert werden können, muss man die Eigenschaft im Konstruktorprototypen setzen und nicht in der Konstruktorfunktion.

- -

Instanzbeziehungen prüfen

- -

Das Nachgucken von Eigenschaften in JavaScript prüft erst die eigenen Eigenschaften und wenn die Eigenschaft dort nicht ist die Eigenschaften der speziellen Eigenschaft __proto__. Das setzt sich rekursiv fort; der Prozess wird "nachschlagen in der Prototypenkette" genannt.

- -

Die spezielle Eigenschaft __proto__ wird beim erstellen des Objektes gesetzt; sie wird auf den Wert der prototype Eigenschaft des Konstruktors gesetzt. Deshalb erstellt der Ausdruck new Foo() ein Objekt mit __proto__ == Foo.prototype. Folglich ändert die Änderung der Foo.prototype Eigenschaft alle Nachschlage Prozesse für alle Objekte, die mit new Foo() erstellt wurden.

- -

Alle Objekte haben eine __proto__ Objekteigenschaft (außer Object); Alle Funktionen haben eine prototype Objekteigenschaft. So können Objekte über 'Prototypenvererbung' mit anderen Objekten verbunden werden. Man kann auf Vererbung testen, indem __proto__ eines Objekts mit einer prototype Objekt einer Funktion verglichen wird. JavaScript hat dafür eine Kurzschreibweise: der instanceof Operator prüft ein Objekt gegen eine Funktion und gibt true zurück, wenn das Objekt von dem Funktionsprototyp erbt. Zum Beispiel:

- -
var f = new Foo();
-var isTrue = (f instanceof Foo);
- -

Für ein detailierteres Beispiel nehmen wir an, dass wir die gleichen Definition wie in Eigenschaften vererben haben. Ein Engineer wird wie folgt erstellt:

- -
var chris = new Engineer('Pigman, Chris', ['jsd'], 'fiji');
-
- -

Mit diesem Objekt, sind alle folgenden Statements true:

- -
chris.__proto__ == Engineer.prototype;
-chris.__proto__.__proto__ == WorkerBee.prototype;
-chris.__proto__.__proto__.__proto__ == Employee.prototype;
-chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype;
-chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
-
- -

Damit kann man eine instanceOf Funktion wie folgt schreiben:

- -
function instanceOf(object, constructor) {
-   object = object.__proto__;
-   while (object != null) {
-      if (object == constructor.prototype)
-         return true;
-      if (typeof object == 'xml') {
-        return constructor.prototype == XML.prototype;
-      }
-      object = object.__proto__;
-   }
-   return false;
-}
-
- -
Hinweis: Die obige Implementierung überprüft den Typ des Objekts gegen "xml", um eine Eigenart der Darstellung von XML-Objekten in neueren JavaScript-Versionen zu umgehen. die wesentlichen Details sind in {{bug(634150)}}, beschrieben.
- -

Der Einsatz der oben definierten instanceOf Funktion führt bei folgenden Ausdrücken zu true:

- -
instanceOf(chris, Engineer)
-instanceOf(chris, WorkerBee)
-instanceOf(chris, Employee)
-instanceOf(chris, Object)
-
- -

Jedoch ist der folgende Ausdruck false:

- -
instanceOf(chris, SalesPerson)
-
- -

Globale Informationen in Konstruktoren

- -

Wenn man einen Konstruktor erstellt, muss man vorsichtig sein, wenn man globale Informationen im Konstruktor einstellt. Nimmt man zum Beispiel an, man möchte eine eindeutige ID, die automatisch für jeden neuen employee zugewiesen wird, kann man die folgende Definition für Employee benutzen:

- -
var idCounter = 1;
-
-function Employee(name, dept) {
-   this.name = name || '';
-   this.dept = dept || 'general';
-   this.id = idCounter++;
-}
-
- -

Wenn man mit dieser Definition ein neuen Employee erstellt, weist der Konstruktor die nächste ID in der Sequenz zu und inkrementiert dann den globalen ID-Zähler. Wenn die nächsten Statemants die folgenden sind, so ist victoria.id == 1 und harry.id == 2:

- -
var victoria = new Employee('Pigbert, Victoria', 'pubs');
-var harry = new Employee('Tschopik, Harry', 'sales');
-
- -

Auf den ersten Blick ist das super. Jedoch wird idCounter jedes mal, wenn ein Employee erstellt wird, wofür auch immer, inkrementiert. Wenn man eine Employee Hierarchie wie im Kapitel oben gezeigt, so wird der Employee Konstruktor für jedes einstellen des Prototypen aufgerufen. Angenommen man hat den folgenden Code:

- -
var idCounter = 1;
-
-function Employee(name, dept) {
-   this.name = name || '';
-   this.dept = dept || 'general';
-   this.id = idCounter++;
-}
-
-function Manager(name, dept, reports) {...}
-Manager.prototype = new Employee;
-
-function WorkerBee(name, dept, projs) {...}
-WorkerBee.prototype = new Employee;
-
-function Engineer(name, projs, mach) {...}
-Engineer.prototype = new WorkerBee;
-
-function SalesPerson(name, projs, quota) {...}
-SalesPerson.prototype = new WorkerBee;
-
-var mac = new Engineer('Wood, Mac');
-
- -

Angenommen die Definitionen lassen hier die base Eigenschaft weg und rufen den Konstruktor oberhalb in der Prototypenkette auf. In diesem Fall, bekommt das mac Objekt die id 5.

- -

Abhängig von der Anwendung ist es sinnvoll oder auch nicht, dass der Zähler an diesen Stellen extra hochzählt. Wenn man an dem exakten Wert des Zählers interessiert ist, ist eine mögliche Lösung den folgenden Konstruktor zu nutzen:

- -
function Employee(name, dept) {
-   this.name = name || '';
-   this.dept = dept || 'general';
-   if (name)
-      this.id = idCounter++;
-}
-
- -

Wenn eine Instanz von Employee erstellt wird, der als Prototyp genutzt wird, übergibt man keine Argumente an den Konstruktor. Benutzt man diese Definition des Konstruktors, wird keine id vergeben und der Zäher nicht aktualisiert, wenn dem Konstruktor keine Argumente übergeben werden. Daraus folgt, dass man einem Employee einen Namen geben muss, damit er eine id erhält. In diesem Beispiel ist mac.id == 1.

- -

Alternativ kann man WorkerBee eine Kopie des Employee Prototypenobjektes zuweisen:

- -
WorkerBee.prototype = Object.create(Employee.prototype);
-// instead of WorkerBee.prototype = new Employee
-
- -

Keine Mehrfachvererbung

- -

Einige objektorientierte SPrachen erlauben Mehrfachvererbung. Das bedeutet, dass ein Objekt die Eigenschaften und Werte von mehreren Elternobjekte erben kann. JavaScript unterstützt keine Mehrfachvererbung.

- -

Vererbung von Eigenschafteswerten funktioniert zu JavaScripts Laufzeit durch das Suchen in der Prototypenkette eines Objektes. Weil ein Objekt ein einzigen Prototypen hat, kann JavaScript nicht dynamisch von mehr als einer Prototypenkette erben.

- -

In JavaScript kann eine Konstruktorfunkton mehrere andere Konstruktorfunktionen in sich aufrufen. Das gibt die Illusion von Mehrfachvererbung. Zum Beispiel die folgenden Statements:

- -
function Hobbyist(hobby) {
-   this.hobby = hobby || 'scuba';
-}
-
-function Engineer(name, projs, mach, hobby) {
-   this.base1 = WorkerBee;
-   this.base1(name, 'engineering', projs);
-   this.base2 = Hobbyist;
-   this.base2(hobby);
-   this.machine = mach || '';
-}
-Engineer.prototype = new WorkerBee;
-
-var dennis = new Engineer('Doe, Dennis', ['collabra'], 'hugo');
-
- -

Vorausgesetzt wird, die Definition von WorkerBee früher in diesem Kapitel. In diesem Fall hat das dennis Objekt die folgenden Eigenschaften:

- -
dennis.name == 'Doe, Dennis';
-dennis.dept == 'engineering';
-dennis.projects == ['collabra'];
-dennis.machine == 'hugo';
-dennis.hobby == 'scuba';
-
- -

dennis hat also die hobby Eigenschaften des Hobbyist Konstruktors bekommen. Setzt man jetzt noch voraus, dass danach Eigenschaften zum Konstruktorprototypen Hobbyist hinzugefügt werde:

- -
Hobbyist.prototype.equipment = ['mask', 'fins', 'regulator', 'bcd'];
-
- -

Das dennis Objekt erbt diese neue Eigenschaft nicht.

- -
{{PreviousNext("Web/JavaScript/Guide/Mit_Objekten_arbeiten", "Web/JavaScript/Guide/Using_promises")}}
diff --git a/files/de/web/javascript/guide/functions/index.html b/files/de/web/javascript/guide/functions/index.html new file mode 100644 index 0000000000..3eeeb4f4e5 --- /dev/null +++ b/files/de/web/javascript/guide/functions/index.html @@ -0,0 +1,657 @@ +--- +title: Funktionen +slug: Web/JavaScript/Guide/Funktionen +tags: + - Beginner + - Functions + - Guide + - JavaScript + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Functions +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Schleifen_und_Iterationen", "Web/JavaScript/Guide/Ausdruecke_und_Operatoren")}}
+ +

Funktionen sind ein Grundbaustein in JavaScript. Eine Funktion ist eine Prozedur - eine Reihe von Anweisungen, um eine Aufgabe auszuführen oder eine Wert auszurechnen. Um Funktionen zu verwenden, müssen diese im Scope (Gültigkeitsbereich) deklariert werden, in dem sie ausgeführt werden soll.

+ +

Siehe ebenfalls in der ausführlichen Referenz über JavaScript Funktionen nach, um noch mehr Detail zu erfahren.

+ +

Funktionen definieren

+ +

Funktionsdeklaration

+ +

Eine Funktionsdefinition (auch Funktionsdeklaration oder Funktionsanweisung genannt) besteht aus dem Schlüsselwort function, gefolgt von:

+ + + +

Das folgende Beispiel definiert eine Funktion mit dem Namen square:

+ +
function square(number) {
+  return number * number;
+}
+
+ +

Die Funktion square nimmt einen Parameter entgegen, welcher number heißt. Die Funktion besteht aus einer Anweisung, die besagt, dass der Parameter der Funktion (das ist number), multipliziert mit sich selbst, zurückgegeben werden soll. Dabei gibt das  return Statement an, welcher Wert von der Funktion zurückzugeben wird.

+ +
return number * number;
+
+ +

Bei Primitive Parameter, wie Zahlen, wird der Funktionen der Wert übergeben. Werte, die der Funktion übergeben wurden und innerhalb der Funktion geändert werden, ändert den Wert zwar innerhalb der Funktion, aber nicht global oder in der aufrufenden Funktion.

+ +

Wird ein Objekt als Parameter übergeben (z. B. ein nicht primitiver Wert wie ein  {{jsxref("Array")}} oder ein selbst definiertes Objekt) und die Funktion ändert die Objekteigenschaften, so sind die Änderungen außerhalb der Funktion sichtbar, wie im folgendem Beispiel veranschaulicht wird:

+ +
function myFunc(theObject) {       //Funktiondekleration
+  theObject.make = 'Toyota';
+}
+
+var mycar = {make: 'Honda', model: 'Accord', year: 1998};
+var x, y;
+
+x = mycar.make;  // x bekommt den Wert "Honda"
+
+myFunc(mycar);
+y = mycar.make;  // y  bekommt den Wert "Toyota"
+                 // (die make Eigenschaft wurde in der Funktion geändert)
+ +

Funktionsausdrücke

+ +

Während die Funktionsdeklarationen oben syntaktisch ein Statement sind, kann eine Funktion auch durch Funktionsausdrücke erstellt werde. Derartige Funktionen können auch anonym sein; denn Funktionen benötigten keinen Namen. So kann zum Beispiel die Funktion square auch so definiert werden:

+ +
var square = function(number) { return number * number; };
+var x = square(4); // x bekommt den Wert 16
+ +

Jedoch kann die Funktion auch einen Name haben, um sich innerhalb der Funktion selbst aufzurufen oder die Funktion im Stack Traces des Debuggers zu identifizieren zu können:

+ +
var factorial = function fac(n) { return n < 2 ? 1 : n * fac(n - 1); };
+
+console.log(factorial(3));
+
+ +

Funktionsausdrücke sind praktisch, um Funktionen als ein Argument einer anderen Funktion zu übergeben. Das folgende Beispiel zeigt die Definition einer map Funktion, die eine Funktion als ersten Parameter erwartet:

+ +
function map(f, a) {
+  var result = [],i; // erstellt ein neues Array
+  for (i = 0; i != a.length; i++)
+    result[i] = f(a[i]);
+  return result;
+}
+
+ +

Im folgenden Quelltext wird einer Funktion eine Funktion übergeben, welche zuvor durch einen Funktions-Ausdruck definiert wurde. Diese Funktion wird für jedes Element in einem Array (zweiter Parameter) ausgeführt.

+ +
function map(f, a) {
+  var result = []; // erstellt ein neues Array
+  var i;
+  for (i = 0; i < a.length; i++) {
+    result[i] = f(a[i]);
+  }
+  return result;
+}
+var f = function(x) {
+  return x * x * x;
+}
+var numbers = [0, 1, 2, 5, 10];
+var cube = map(f,numbers);
+console.log(cube);
+
+ +

gibt [0, 1, 8, 125, 1000]  zurück.

+ +

In JavaScript kann eine Funktion definiert werden, wenn eine Bedingung erfüllt ist. Zum Beispiel wird myFunc nur definiert, wenn num gleich 0 ist:

+ +
var myFunc;
+if (num === 0) {
+  myFunc = function(theObject) {
+    theObject.make = 'Toyota';
+  }
+}
+ +

Im Unterschied zu den hier gezeigten Funktionsdeklarationen, kann man auch den {{jsxref("Function")}} Konstruktor verwenden, um eine Funktion von einem String zur Laufzeit zu erstellen, ähnlich der {{jsxref("eval()")}} Funktion.

+ +

Eine Methode ist eine Funktion, die Eigenschaft eines Objektes ist. Mehr Informationen über Objekt und Methoden sind im Artikel "Mit Objekten arbeiten" zu finden.

+ +

Aufruf von Funktionen

+ +

Das Definieren einer Funktion führen diese noch nicht aus. Die Definition gibt der Funktion lediglich einen Namen und beschreibt was geschehen soll, wenn die Funktion aufgerufen wird. Erst der Aufruf ermöglicht es die Aktionen mit den angegebenen Parametern durchzuführen. Zum Beispiel wird die vorher definierte Funktion square so aufgerufen:

+ +
square(5);
+
+ +

Es wird die Funktion mit dem Argument 5 aufgerufen. Die Funktion führt ihre Anweisungen aus und gibt den Wert 25 zurück.

+ +

Funktionen müssen im Scope (Gültigkeitsbereich) sein, wenn sie aufgerufen werden, können jedoch auch erst später definiert werden, wie im folgenden Beispiel:

+ +
console.log(square(5));
+/* ... */
+function square(n) { return n * n; }
+
+ +

Der Scope einer Funktion ist die Funktion in der sie deklariert wird, oder das gesamte Programm, falls sie auf oberster Ebene deklariert wird.

+ +
+

Hinweis: Nur die oben angegebene Syntax für Funktionen wird funktionieren (function funcName(){}). Der folgende Code funktioniert nicht. Das bedeutet, dass das nur mit Funktionsdeklarationen funktioniert aber nicht mit Funktionsausdrücken.

+
+ +
console.log(square); // square ist mit dem Initialwert undefined gehoisted.
+console.log(square(5)); // TypeError: square is not a function
+var square = function(n) {
+  return n * n;
+}
+
+ +

Die Argumente einer Funktion sind nicht auf Strings und Nummern limitiert, denn es können auch ganze Objekte übergeben werden. Die showProps() Funktion (definiert in Beitrag "Arbeiten mit Objekten") ist ein Beispiel für einer Funktion, die Objekte als Argument entgegennimmt.

+ +

Eine Funktion kann sich selbst Aufrufen. Zum Beispiel berechnet folgende Funktion die Fakultät rekursiv:

+ +
function factorial(n) {
+  if ((n === 0) || (n === 1))
+    return 1;
+  else
+    return (n * factorial(n - 1));
+}
+
+ +

Die Fakultät von 1 bis 5 kann wie folgt berechnet werden:

+ +
var a, b, c, d, e;
+a = factorial(1); // a wird der Wert 1 zugewiesen
+b = factorial(2); // b wird der Wert 2 zugewiesen
+c = factorial(3); // c wird der Wert 6 zugewiesen
+d = factorial(4); // d wird der Wert 24 zugewiesen
+e = factorial(5); // e wird der Wert 120 zugewiesen
+
+ +

Es gibt aber noch weitere Möglichkeiten Funktionen aufzurufen. Oftmals gibt es Fälle, in denen Funktionen dynamisch aufgerufen werden müssen, die Anzahl der Argumente variiert oder der Kontext einer Funktion zur Laufzeit gesetzt werden muss. Das zieht nach sich, dass Funktionen selbst Objekte sind, die Methoden haben (siehe das {{jsxref("Function")}} Objekt). Eine diese Methoden ist die {{jsxref("Function.apply", "apply()")}} Methode, mit der man die oben genannten Aufgaben lösen kann.

+ +

Scopes (Gültigkeitsbereiche) von Funktionen

+ +

Variablen, die in einer Funktion definiert werden, können nicht außerhalb der Funktion erreicht werden, weil die Variablen nur im Scope (Gültigkeitbereich) der Funktion definiert sind. Im Gegensatz dazu kann eine Funktion alle Variablen und Funktionen erreichen, die in dem Scope definiert wurden, in dem auch die Funktion definiert wurde. Anders gesagt kann eine Funktion, die im globalen Scope definiert wurde, alle Variablen und Funktionen des globalen Scopes erreichen. Wenn eine Funktion in einer Funktion definiert wird, kann die innere Funktion auf alle Definitionen seiner Elternfunktion und alle Definitionen, auf die die Elternfunktion Zugriff hat, zugreifen.

+ +
// Die folgenden Variablen sind im globalen Scope definiert
+var num1 = 20,
+    num2 = 3,
+    name = 'Chamahk';
+
+// Diese Funktion ist im globalen Scope definiert
+function multiply() {
+  return num1 * num2;
+}
+
+multiply(); // gibt 60 zurück
+
+// Ein Beispiel für verschachtelte Funktionen
+function getScore() {
+  var num1 = 2,
+      num2 = 3;
+
+  function add() {
+    return name + ' scored ' + (num1 + num2);
+  }
+
+  return add();
+}
+
+getScore(); // gibt "Chamahk scored 5" zurück
+
+ +

Scope und der Funktionsstack

+ +

Rekursion

+ +

Eine Funktion kann sich selbst referenzieren und aufrufen. Dabei gibt es drei Möglichkeiten, wie eine Funktion sich selbst referenzieren kann:

+ +
    +
  1. Der Funktionsname
  2. +
  3. arguments.callee
  4. +
  5. Eine im Scope liegende Variable, die auf die Funktion referenziert.
  6. +
+ +

Nimmt man zum Beispiel folgende Funktion:

+ +
var foo = function bar() {
+   // Anweisungen
+};
+
+ +

Folgende Anweisungen im Körper der Funktion bewirken alle das Gleiche:

+ +
    +
  1. bar()
  2. +
  3. arguments.callee()
  4. +
  5. foo()
  6. +
+ +

Eine Funktion, die sich selbst aufruft, wird rekursive Funktion genannt. Rekursion ist dabei vergleichbar mit einer Schleife. Beide führen den selben Quelltext mehrfach aus und beide benötigen eine Bedingung (um eine unendliche Schleife zu vermeiden oder eine unendliche Rekursion zu vermeiden). Das nächste Beispiel zeigt eine Schleife:

+ +
var x = 0;
+while (x < 10) { // "x < 10" ist die Schleifenbedingung
+   // do stuff
+   x++;
+}
+
+ +

Diese Schleife kann in eine rekursive Funktion konvertiert werden, die aufgerufen wird:

+ +
function loop(x) {
+  if (x >= 10) // "x >= 10" ist die Abbruchbedingung (gleich zu "!(x < 10)")
+    return;
+  // do stuff
+  loop(x + 1); // der rekursive Aufruf
+}
+loop(0);
+
+ +

Jedoch können manche Algorithmen nicht in eine einfache Schleife umgewandelt werden. Zum Beispiel kann das Abrufen aller Knoten einer Baumstruktur (z. B. DOM) einfacher rekursiv realisieren werden:

+ +
function walkTree(node) {
+  if (node == null) //
+    return;
+  // do something with node
+  for (var i = 0; i < node.childNodes.length; i++) {
+    walkTree(node.childNodes[i]);
+  }
+}
+
+ +

Verglichen mit der Funktion loop, erzeugt hier jeder rekursive Aufruf mehrere weitere rekursive Aufrufe.

+ +

Es ist möglich jeden rekursiven Algorithmus in einen nicht rekursiven umzuwandeln, jedoch ist die Logik oftmals sehr viel komplexer und es wird ein zusätzlicher Stack benötigt. Rekursion nutzt ebenfalls einen Stack: den Funktionsstack.

+ +

Die Stack-ähnliche Funktionsweise kann in folgendem Beispiel betrachtet werden:

+ +
function foo(i) {
+  if (i < 0)
+    return;
+  console.log('begin:' + i);
+  foo(i - 1);
+  console.log('end:' + i);
+}
+foo(3);
+
+// Output:
+
+// begin: 3
+// begin: 2
+// begin: 1
+// begin: 0
+// end: 0
+// end: 1
+// end: 2
+// end: 3
+ +

Verschachtelte Funktionen und Closures

+ +

Man kann eine Funktion in eine andere verschachteln. Die verschachtelte (innere) Funktion ist privat innerhalb ihrer Containerfunktion (äußere Funktion). Sie formt auch eine Closure. Eine Closure ist ein Ausdruck, der freie Variablen enthalten kann, (typischerweise eine Funktion) zusammen mit einer Umgebung, welche die diese Variablen einschließt (und damit den Ausdruck abschließt, daher der Name closure).

+ +

Weil eine verschachtelte Funktion eine Closure ist, bedeutet das, dass sie die Argumente und Variablen ihrer Containerfunktion vererbt bekommt. Anders gesagt enthält der Scope der inneren Funktion den Scope der äußeren Funktion.

+ +

Zusammenfassend:

+ + + +

Im folgenden Beispiel werden innere Funktionen gezeigt:

+ +
function addSquares(a, b) {
+  function square(x) {
+    return x * x;
+  }
+  return square(a) + square(b);
+}
+a = addSquares(2, 3); // gibt 13 zurück
+b = addSquares(3, 4); // gibt 25 zurück
+c = addSquares(4, 5); // gibt 41 zurück
+
+ +

Weil die innere Funktion eine Closure formt, kann die äußere Funktion aufgerufen werden und Argumente für die innere und äußere Funktion spezifizieren::

+ +
function outside(x) {
+  function inside(y) {
+    return x + y;
+  }
+  return inside;
+}
+fn_inside = outside(3);  // Man kann sich das folgendermaßen vorstellen
+                         // gib mir eine Funktion, die 3 zu einem Parameter addiert.
+result = fn_inside(5);   // gibt 8 zurück
+
+result1 = outside(3)(5); // gibt 8 zurück
+
+ +

Erhaltung von Variablen

+ +

Bemerkenswert ist, dass x erhalten wird, wenn inside zurückgegeben wird. Eine Closure muss alle Argumente und Variablen erhalten, die sie referenziert. Weil jeder Aufruf potenziell verschiedene Argumente benötigt, wird eine neue Closure für jeden Aufruf erstellt. Der Speicher kann nur freigegeben werden, wenn die zurückgegebene inside Funktion nicht mehr erreichbar ist.

+ +

Das ist nicht anders mit gespeicherten Referenzen in anderen Objekten, jedoch oftmals weniger deutlich, weil man diese nicht direkt referenziert und nicht inspizieren kann.

+ +

Mehrfach verschachtelte Funktionen

+ +

Funktionen können mehrfach verschachtelt sein, z. B. eine Funktion (A) enthält eine Funktion (B), die eine Funktion (C) enthält. Beide Funktionen, B und C sind Closures, B kann A erreichen und C kann B erreichen. Zudem kann C auch A erreichen, weil C B erreichen kann und B A erreichen kann. Deswegen kann eine Closure mehrere Scopes enthalten.; sie enthält rekursiv die Scopes der Funktion, die der Container ist. Das wird Scopeverkettung (scope chaining) genannt.

+ +

Untersuche das nächste Beispiel:

+ +
function A(x) {
+  function B(y) {
+    function C(z) {
+      console.log(x + y + z);
+    }
+    C(3);
+  }
+  B(2);
+}
+A(1); // logs 6 (1 + 2 + 3)
+
+ +

In diesem Beispiel benutzt C die Variablen y, von B, und x, von A. Das kann gemacht werden weil:

+ +
    +
  1. B ist eine Closure, die A enthält, z. B. B kann die Argumente und Variablen von A benutzen.
  2. +
  3. C ist ein Closure, die B enthält.
  4. +
  5. Weil die Closure von B auf A zugreifen kann, kann die Closure von C auf die Argumente und Variablen von A und B zugreifen. Anders gesagt verkettet C den Scope von B und A in dieser Reihenfolge.
  6. +
+ +

Das umgekehrte ist nicht möglich. A kann nicht auf C zugreifen, weil A nicht auf die Variablen und Argumente von B zugreifen kann und C eine Variable von B ist. So bleibt C für B privat.

+ +

Namenskonflikte

+ +

Wenn zwei Argumente oder Variablen in dem Scope einer Closure mit dem gleichen Namen existieren, gibt es einen Namenskonflikt. Der innerste Scope hat dann Vorrang, was bedeutet, dass der innerste Scope die höchste Priorität hat, während der äußerste Scope die geringste Priorität hat. Das ist wegen der Scopeverkettung. Das erste Glied in der Kette ist der innerste Scope und das letzt Glied ist der äußerste Scope. Dieses ist im folgenden Beispiel zu sehen:

+ +
function outside() {
+  var x = 10;
+  function inside(x) {
+    return x;
+  }
+  return inside;
+}
+result = outside()(20); // gibt 20 statt 10 zurück
+
+ +

Der Namenskonflikt tritt beim der Anweisung return x auf und ist zwischen dem Parmeter x von inside und der Variable x von outside. Die Scopekette ist hier {inside, outside, globales Objekt}. Dabei bekommt x von inside eine höhere Priorität als das x von outside. und 20 wird statt der 10 zurückgegeben.

+ +

Closures

+ +

Closures sind eines der mächtigsten Funktionen von JavaScript. JavaScript unterstützt das Verschachteln von Funktionen und erlaubt der inneren Funktionen den vollen Zugriff auf alle definierten Variablen und Funktionen der äußeren Funktion (und alle anderen Variablen und Funktionen die die äußere Funktion erreichen kann). Jedoch hat die äußere Funktion keinen Zugriff auf die Variablen und Funktione, die in der innere Funktion definiert werden. Das unterstützt mehr oder weniger Sicherheit für die Variablen der inneren Funktion. Wenn die innere Funktion Zugriff auf den Scope der äußeren Funktion hat, müssen die Variablen und Funktionen der äußeren Funktion länger leben, als die Ausführungen der inneren Funktion, weil die innere Funktion das Überleben der äußeren Funktion managet. Eine Closure wird erstellt, wenn die innere Funktion irgendwie in einem äußeren Scope der äußeren Funktion erreichbar gemacht wird.

+ +
var pet = function(name) {   // Die äußere Funktion definiert eine Variable "name"
+  var getName = function() {
+    return name;             // Die innere Funktion hat Zugriff auf die "name" Variable der äußeren Funktion
+  }
+  return getName;            // gibt die innere Funktion zurück
+}
+myPet = pet('Vivie');
+
+myPet();                     // gibt "Vivie" zurück
+
+ +

Es kann viel komplexer sein, als der oben gezeigte Quelltext. Ein Objekt enthält Methoden zum verändern von inneren Variablen der äußeren Funktion.

+ +
var createPet = function(name) {
+  var sex;
+
+  return {
+    setName: function(newName) {
+      name = newName;
+    },
+
+    getName: function() {
+      return name;
+    },
+
+    getSex: function() {
+      return sex;
+    },
+
+    setSex: function(newSex) {
+      if(typeof newSex === 'string' && (newSex.toLowerCase() === 'male' || newSex.toLowerCase() === 'female')) {
+        sex = newSex;
+      }
+    }
+  }
+}
+
+var pet = createPet('Vivie');
+pet.getName();                  // Vivie
+
+pet.setName('Oliver');
+pet.setSex('male');
+pet.getSex();                   // male
+pet.getName();                  // Oliver
+
+ +

Im Quelltext oben ist die name Variable der äußeren Funktion in den inneren Funktionen erreichbar und es gibt keine andere Möglichkeit die inneren Variablen zu erreichen, als über die inneren Funktion. Die innere Variable der inneren Funktion fungiert als sicherer Speicher für die äußeren Parameter und Variablen. Sie enthalten permanent und sicher die Daten mit denen die innere Funktion arbeitet. Die Funktion hat niemals eine Variable beschrieben noch hat sie einen Namen.

+ +
var getCode = (function() {
+  var secureCode = '0]Eal(eh&2';    // Ein Code der nicht von Außerhalb verändert werden soll
+
+  return function () {
+    return secureCode;
+  };
+}());
+
+getCode();    // gibt secureCode zurück.
+
+ +

Es gibt aber eine menge von Tücken, die der Einsatz von Closures mit sich bringt. Wenn eine innere Funktion eine Variable definiert, die den gleichen Namen wie eine Variable im äußeren Scope hat, kann die äußere Variable nicht mehr referenziert werden.

+ +
var createPet = function(name) {  // Äußere Funktion definiert die Variable "name"
+  return {
+    setName: function(name) {    // Innere Funktion definiert ebenfalls eine Variable "name"
+      name = name;               // Wie referenziert man die Variable "name" der äußeren Funktion?
+    }
+  }
+}
+
+ +

Einsatz des arguments Objekts

+ +

Die Argumente einer Funktion werden in einem Array-ähnlichen Objekt gewartet. In einer Funktion können die Argumente wie folgt adressiert werden:

+ +
arguments[i]
+
+ +

i ist die Ordnungsnummer des Arguments, beginnend bei null. So ist das erste übergebene Argument einer Funktion arguments[0]. Die Anzahl der übergebenen Argumente ist arguments.length.

+ +

Mit dem arguments Objekt kann man eine Funktion mit mehr Agumenten aufrufen als sie formal deklariert wurden. Das ist oft nützlich, wenn man nicht weiß, wie viele Argumente einer Funktion übergeben werden. Mit arguments.length kann die Anzahl der Argumente, die einer Funktion übergeben wurde, ermittelt werden. Über das arguments Objekt können dann alle Argumente gelesen werden.

+ +

Zum Beispiel kann es eine Funktion geben, die verschieden viele Strings zusammenfügt. Das einzige formale Argument der Funktion ist das Trennzeichen, welches die Zeichen definiert, die zwischen den Strings eingefügt werden. Im folgenden Quelltext ist die Funktion implementiert:

+ +
function myConcat(separator) {
+   var result = ''; // initialize list
+   var i;
+   // iterate through arguments
+   for (i = 1; i < arguments.length; i++) {
+      result += arguments[i] + separator;
+   }
+   return result;
+}
+
+ +

Man kann der Funktion jede Anzahl an Argumenten übergeben und die Funktion fügt die Argumente in einem String zusammen:

+ +
// returns "red, orange, blue, "
+myConcat(', ', 'red', 'orange', 'blue');
+
+// returns "elephant; giraffe; lion; cheetah; "
+myConcat('; ', 'elephant', 'giraffe', 'lion', 'cheetah');
+
+// returns "sage. basil. oregano. pepper. parsley. "
+myConcat('. ', 'sage', 'basil', 'oregano', 'pepper', 'parsley');
+
+ +
+

Hinweis: Die arguments Variable ist "Array-ähnlich", aber kein Array. Es ist Array-ähnlich indem es nummerierte Indizes und eine length Eigenschaft hat. Jedoch unterstützt es nicht alle Array-Manipulations-Methoden.

+
+ +

Siehe im {{jsxref("Function")}} Objekt in den JavaScript Referenzen für mehr Informationen.

+ +

Funktionsparameter

+ +

Mit ECMAScript 2015, gibt es zwei neue Arten von Parametern: Default-Parameter und Rest-Parameter.

+ +

Default-Parameter

+ +

In JavaScript ist der Standardwert eines Parameters undefined. In manchen Situationen ist es sinnvoll den Standardwert auf einen anderen Wert zu setzen. Das ist das Einsatzgebiet von Default-Parametern.

+ +

In der Vergangenheit war die Strategie für das Setzen von Standardwerten, dass im Körper der Funktion geprüft wird, ob ein Parameter undefined ist und ihn in diesem Fall neu zu beschreiben. Wenn im folgenden Beispiel kein Argument b übergeben wird, wird dieser undefined sein und die Auswertung von a*b wird NaN sein. Deswegen ist dieser Fall in der zweiten Zeile des Beispiels abgefangen:

+ +
function multiply(a, b) {
+  b = typeof b !== 'undefined' ?  b : 1;
+
+  return a * b;
+}
+
+multiply(5); // 5
+
+ +

Mit Default-Parametern ist die Überprüfung im Körper der Funktion nicht mehr nötig. Jetzt kann man 1 als Standardwert für b im Funktionskopf angeben:

+ +
function multiply(a, b = 1) {
+  return a * b;
+}
+
+multiply(5); // 5
+ +

Für mehr Details, siehe in den Referenzen unter Default-Parameter.

+ +

Rest-Parameter

+ +

Die Rest-Parameter Syntax ermöglicht er eine unendliche Anzahl von Argumenten als Array zu repräsentieren. Im Beispiel wird der Rest-Parameter eingesetzt um die alle Argumente ab dem zweiten Argument zu sammeln. Danach werden diese mit dem ersten Parameter multipliziert. Dieses Beispiel benutzt Pfeilfunktionen, welche in nächsten Kapitel erklärt werden:

+ +
function multiply(multiplier, ...theArgs) {
+  return theArgs.map(x => multiplier * x);
+}
+
+var arr = multiply(2, 1, 2, 3);
+console.log(arr); // [2, 4, 6]
+ +

Pfeilfunktionen

+ +

Ein Pfeilfunktions Ausdruck hat eine kürzere Syntax verglichen mit Funktionsausdrücken und bindet lexikalisch den this Wert. Pfeilfunktionen sind immer anonym. Sie dazu auch den hacks.mozilla.org Blogbeitrag: "ES6 In Depth: Arrow functions".

+ +

Zwei Faktoren haben die Einführung von Pfeilfunktionen beeinflusst: kürzere Funktionen und lexikalisches this.

+ +

Kürzere Funktionen

+ +

In manchen funktionalen Patterns sind kurze Funktionen willkommen. Vergleiche:

+ +
var a = [
+  'Hydrogen',
+  'Helium',
+  'Lithium',
+  'Beryl­lium'
+];
+
+var a2 = a.map(function(s) { return s.length; });
+
+console.log(a2); // logs [8, 6, 7, 9]
+
+var a3 = a.map( s => s.length );
+
+console.log(a3); // logs [8, 6, 7, 9]
+
+ +

Lexikalisches this

+ +

Bis es Pfeilfunktionen gab, hat jede neue Funktion sein eigenen this Wert definiert (ein neues Objekt in Fällen eines Konstruktors, undefined in Funktionsaufrufen im strict mode, das Kontextobjekt, wenn eine Funktion als Objektmethode aufgerufen wird, etc.). Das ist lästig mit objektorientierten Programmierstilen.

+ +
function Person() {
+  // The Person() constructor defines `this` as itself.
+  this.age = 0;
+
+  setInterval(function growUp() {
+    // In nonstrict mode, the growUp() function defines `this`
+    // as the global object, which is different from the `this`
+    // defined by the Person() constructor.
+    this.age++;
+  }, 1000);
+}
+
+var p = new Person();
+ +

In ECMAScript 3/5, wurde dieses Problem behoben, indem der Wert der Variablen this in einer weiteren Variablen gespeichert wird.

+ +
function Person() {
+  var self = this; // Some choose `that` instead of `self`.
+                   // Choose one and be consistent.
+  self.age = 0;
+
+  setInterval(function growUp() {
+    // The callback refers to the `self` variable of which
+    // the value is the expected object.
+    self.age++;
+  }, 1000);
+}
+ +

Alternativ kann eine gebundene Funktion  erstellt werden, so dass der Wert für this mit übergeben werden kann.

+ +

Pfeilfunktionen nutzen den this Wert des umschließenden Kontextes, so dass der folgende Quelltext wie erwartet funktioniert:

+ +
function Person() {
+  this.age = 0;
+
+  setInterval(() => {
+    this.age++; // |this| properly refers to the person object
+  }, 1000);
+}
+
+var p = new Person();
+ +

Vordefinierte Funktionen

+ +

JavaScript hat einige eingebaute Funktionen:

+ +
+
{{jsxref("Global_Objects/eval", "eval()")}}
+
+

Die eval() Methode wertet JavaScript Quelltext repräsentiert als String aus.

+
+
{{jsxref("Global_Objects/uneval", "uneval()")}} {{non-standard_inline}}
+
+

Die uneval() Methode erstellt einen String der Quelltext eines {{jsxref("Object")}}s repräsentiert.

+
+
{{jsxref("Global_Objects/isFinite", "isFinite()")}}
+
+

Die globale isFinite() Funktion ob ein übergebener Wert endlich ist. Der übergebene Wert wird, wenn es nötig ist, zu einer Zahl konvertiert.

+
+
{{jsxref("Global_Objects/isNaN", "isNaN()")}}
+
Die isNaN() Funktion überprüft, ob ein Wert {{jsxref("Global_Objects/NaN", "NaN")}} ist oder nicht. Hinweis: Wegen einigen Zwängen innerhalb der isNaN Funktion gibt es interessante Regeln; alternativ kann auch die in  ECMAScript 2015 definierte Funktion Funktion {{jsxref("Number.isNaN()")}} oder der Operator typeof verwendet werden, um einen {{jsxref("Global_Objects/NaN", "NaN")}} Wert zu erkennen.
+
{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}
+
+

Doe parseFloat() Funktion liest einen String als Argument ein und gibt eine Gleitkommazahl zurück.

+
+
{{jsxref("Global_Objects/parseInt", "parseInt()")}}
+
+

Die parseInt() Funktion liest einen String als Argument ein und gibt eine ganze Zahl der Spezifizierten Basis zurück (die Basis ist in der Mathematik das Zahlensystem).

+
+
{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}
+
+

Die decodeURI() Methode decodiert einen Uniform Resource Identifier (URI), der vorher mit der {{jsxref("Global_Objects/encodeURI", "encodeURI")}} Funktion order einer ähnlichen Funktion erstellt wurde.

+
+
{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}
+
+

Die decodeURIComponent() Methode decodiert eine Uniform Resource Identifier (URI) Komponente, die vorher mit der {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} Funktion oder einer ähnlichen Funktion erstellt wurde.

+
+
{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}
+
+

Die encodeURI() Methode codiert einen Uniform Resource Identifier (URI), indem jedes besondere Zeilen durch eine Sequenz aus zwei drei oder vier Zeichen escaped wird. Dieses Sequenzen Repräsentieren die UTF-8 Darstellung der Zeichen (wird nur vier escape Sequenzen von Zeichen zu zwei zwei Platzhalterzeichen umwandeln)

+
+
{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}
+
+

Die encodeURIComponent() Methode codiert eine Uniform Resource Identifier (URI) Komponente, indem jedes besondere Zeilen durch eine Sequenz aus zwei drei oder vier Zeichen escaped wird. Dieses Sequenzen Repräsentieren die UTF-8 Darstellung der Zeichen (wird nur vier escape Sequenzen von Zeichen zu zwei zwei Platzhalterzeichen umwandeln)

+
+
{{jsxref("Global_Objects/escape", "escape()")}} {{deprecated_inline}}
+
+

Die veraltete escape() Methode berechnet einen neuen String indem manche Zeichen durch Hexadezimalsequenzen ersetzt werden. Man sollte {{jsxref("Global_Objects/encodeURI", "encodeURI")}} oder {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} stattdessen benutzen.

+
+
{{jsxref("Global_Objects/unescape", "unescape()")}} {{deprecated_inline}}
+
+

Die veraltete unescape() Methode berechnet einen neuen String indem Hexadezimalsequenzen durch die repräsentierenden Zeichen ersetzt werden. Die Hexadezimalsequenzen können von Funktionen wie {{jsxref("Global_Objects/escape", "escape")}} eingeführt werden. Weil unescape() veraltet ist, sollte man stattdessen die Funktion {{jsxref("Global_Objects/decodeURI", "decodeURI()")}} oder {{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent")}} benutzen.

+
+
+ +

{{PreviousNext("Web/JavaScript/Guide/Schleifen_und_Iterationen", "Web/JavaScript/Guide/Ausdruecke_und_Operatoren")}}

diff --git a/files/de/web/javascript/guide/funktionen/index.html b/files/de/web/javascript/guide/funktionen/index.html deleted file mode 100644 index 3eeeb4f4e5..0000000000 --- a/files/de/web/javascript/guide/funktionen/index.html +++ /dev/null @@ -1,657 +0,0 @@ ---- -title: Funktionen -slug: Web/JavaScript/Guide/Funktionen -tags: - - Beginner - - Functions - - Guide - - JavaScript - - 'l10n:priority' -translation_of: Web/JavaScript/Guide/Functions ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Schleifen_und_Iterationen", "Web/JavaScript/Guide/Ausdruecke_und_Operatoren")}}
- -

Funktionen sind ein Grundbaustein in JavaScript. Eine Funktion ist eine Prozedur - eine Reihe von Anweisungen, um eine Aufgabe auszuführen oder eine Wert auszurechnen. Um Funktionen zu verwenden, müssen diese im Scope (Gültigkeitsbereich) deklariert werden, in dem sie ausgeführt werden soll.

- -

Siehe ebenfalls in der ausführlichen Referenz über JavaScript Funktionen nach, um noch mehr Detail zu erfahren.

- -

Funktionen definieren

- -

Funktionsdeklaration

- -

Eine Funktionsdefinition (auch Funktionsdeklaration oder Funktionsanweisung genannt) besteht aus dem Schlüsselwort function, gefolgt von:

- - - -

Das folgende Beispiel definiert eine Funktion mit dem Namen square:

- -
function square(number) {
-  return number * number;
-}
-
- -

Die Funktion square nimmt einen Parameter entgegen, welcher number heißt. Die Funktion besteht aus einer Anweisung, die besagt, dass der Parameter der Funktion (das ist number), multipliziert mit sich selbst, zurückgegeben werden soll. Dabei gibt das  return Statement an, welcher Wert von der Funktion zurückzugeben wird.

- -
return number * number;
-
- -

Bei Primitive Parameter, wie Zahlen, wird der Funktionen der Wert übergeben. Werte, die der Funktion übergeben wurden und innerhalb der Funktion geändert werden, ändert den Wert zwar innerhalb der Funktion, aber nicht global oder in der aufrufenden Funktion.

- -

Wird ein Objekt als Parameter übergeben (z. B. ein nicht primitiver Wert wie ein  {{jsxref("Array")}} oder ein selbst definiertes Objekt) und die Funktion ändert die Objekteigenschaften, so sind die Änderungen außerhalb der Funktion sichtbar, wie im folgendem Beispiel veranschaulicht wird:

- -
function myFunc(theObject) {       //Funktiondekleration
-  theObject.make = 'Toyota';
-}
-
-var mycar = {make: 'Honda', model: 'Accord', year: 1998};
-var x, y;
-
-x = mycar.make;  // x bekommt den Wert "Honda"
-
-myFunc(mycar);
-y = mycar.make;  // y  bekommt den Wert "Toyota"
-                 // (die make Eigenschaft wurde in der Funktion geändert)
- -

Funktionsausdrücke

- -

Während die Funktionsdeklarationen oben syntaktisch ein Statement sind, kann eine Funktion auch durch Funktionsausdrücke erstellt werde. Derartige Funktionen können auch anonym sein; denn Funktionen benötigten keinen Namen. So kann zum Beispiel die Funktion square auch so definiert werden:

- -
var square = function(number) { return number * number; };
-var x = square(4); // x bekommt den Wert 16
- -

Jedoch kann die Funktion auch einen Name haben, um sich innerhalb der Funktion selbst aufzurufen oder die Funktion im Stack Traces des Debuggers zu identifizieren zu können:

- -
var factorial = function fac(n) { return n < 2 ? 1 : n * fac(n - 1); };
-
-console.log(factorial(3));
-
- -

Funktionsausdrücke sind praktisch, um Funktionen als ein Argument einer anderen Funktion zu übergeben. Das folgende Beispiel zeigt die Definition einer map Funktion, die eine Funktion als ersten Parameter erwartet:

- -
function map(f, a) {
-  var result = [],i; // erstellt ein neues Array
-  for (i = 0; i != a.length; i++)
-    result[i] = f(a[i]);
-  return result;
-}
-
- -

Im folgenden Quelltext wird einer Funktion eine Funktion übergeben, welche zuvor durch einen Funktions-Ausdruck definiert wurde. Diese Funktion wird für jedes Element in einem Array (zweiter Parameter) ausgeführt.

- -
function map(f, a) {
-  var result = []; // erstellt ein neues Array
-  var i;
-  for (i = 0; i < a.length; i++) {
-    result[i] = f(a[i]);
-  }
-  return result;
-}
-var f = function(x) {
-  return x * x * x;
-}
-var numbers = [0, 1, 2, 5, 10];
-var cube = map(f,numbers);
-console.log(cube);
-
- -

gibt [0, 1, 8, 125, 1000]  zurück.

- -

In JavaScript kann eine Funktion definiert werden, wenn eine Bedingung erfüllt ist. Zum Beispiel wird myFunc nur definiert, wenn num gleich 0 ist:

- -
var myFunc;
-if (num === 0) {
-  myFunc = function(theObject) {
-    theObject.make = 'Toyota';
-  }
-}
- -

Im Unterschied zu den hier gezeigten Funktionsdeklarationen, kann man auch den {{jsxref("Function")}} Konstruktor verwenden, um eine Funktion von einem String zur Laufzeit zu erstellen, ähnlich der {{jsxref("eval()")}} Funktion.

- -

Eine Methode ist eine Funktion, die Eigenschaft eines Objektes ist. Mehr Informationen über Objekt und Methoden sind im Artikel "Mit Objekten arbeiten" zu finden.

- -

Aufruf von Funktionen

- -

Das Definieren einer Funktion führen diese noch nicht aus. Die Definition gibt der Funktion lediglich einen Namen und beschreibt was geschehen soll, wenn die Funktion aufgerufen wird. Erst der Aufruf ermöglicht es die Aktionen mit den angegebenen Parametern durchzuführen. Zum Beispiel wird die vorher definierte Funktion square so aufgerufen:

- -
square(5);
-
- -

Es wird die Funktion mit dem Argument 5 aufgerufen. Die Funktion führt ihre Anweisungen aus und gibt den Wert 25 zurück.

- -

Funktionen müssen im Scope (Gültigkeitsbereich) sein, wenn sie aufgerufen werden, können jedoch auch erst später definiert werden, wie im folgenden Beispiel:

- -
console.log(square(5));
-/* ... */
-function square(n) { return n * n; }
-
- -

Der Scope einer Funktion ist die Funktion in der sie deklariert wird, oder das gesamte Programm, falls sie auf oberster Ebene deklariert wird.

- -
-

Hinweis: Nur die oben angegebene Syntax für Funktionen wird funktionieren (function funcName(){}). Der folgende Code funktioniert nicht. Das bedeutet, dass das nur mit Funktionsdeklarationen funktioniert aber nicht mit Funktionsausdrücken.

-
- -
console.log(square); // square ist mit dem Initialwert undefined gehoisted.
-console.log(square(5)); // TypeError: square is not a function
-var square = function(n) {
-  return n * n;
-}
-
- -

Die Argumente einer Funktion sind nicht auf Strings und Nummern limitiert, denn es können auch ganze Objekte übergeben werden. Die showProps() Funktion (definiert in Beitrag "Arbeiten mit Objekten") ist ein Beispiel für einer Funktion, die Objekte als Argument entgegennimmt.

- -

Eine Funktion kann sich selbst Aufrufen. Zum Beispiel berechnet folgende Funktion die Fakultät rekursiv:

- -
function factorial(n) {
-  if ((n === 0) || (n === 1))
-    return 1;
-  else
-    return (n * factorial(n - 1));
-}
-
- -

Die Fakultät von 1 bis 5 kann wie folgt berechnet werden:

- -
var a, b, c, d, e;
-a = factorial(1); // a wird der Wert 1 zugewiesen
-b = factorial(2); // b wird der Wert 2 zugewiesen
-c = factorial(3); // c wird der Wert 6 zugewiesen
-d = factorial(4); // d wird der Wert 24 zugewiesen
-e = factorial(5); // e wird der Wert 120 zugewiesen
-
- -

Es gibt aber noch weitere Möglichkeiten Funktionen aufzurufen. Oftmals gibt es Fälle, in denen Funktionen dynamisch aufgerufen werden müssen, die Anzahl der Argumente variiert oder der Kontext einer Funktion zur Laufzeit gesetzt werden muss. Das zieht nach sich, dass Funktionen selbst Objekte sind, die Methoden haben (siehe das {{jsxref("Function")}} Objekt). Eine diese Methoden ist die {{jsxref("Function.apply", "apply()")}} Methode, mit der man die oben genannten Aufgaben lösen kann.

- -

Scopes (Gültigkeitsbereiche) von Funktionen

- -

Variablen, die in einer Funktion definiert werden, können nicht außerhalb der Funktion erreicht werden, weil die Variablen nur im Scope (Gültigkeitbereich) der Funktion definiert sind. Im Gegensatz dazu kann eine Funktion alle Variablen und Funktionen erreichen, die in dem Scope definiert wurden, in dem auch die Funktion definiert wurde. Anders gesagt kann eine Funktion, die im globalen Scope definiert wurde, alle Variablen und Funktionen des globalen Scopes erreichen. Wenn eine Funktion in einer Funktion definiert wird, kann die innere Funktion auf alle Definitionen seiner Elternfunktion und alle Definitionen, auf die die Elternfunktion Zugriff hat, zugreifen.

- -
// Die folgenden Variablen sind im globalen Scope definiert
-var num1 = 20,
-    num2 = 3,
-    name = 'Chamahk';
-
-// Diese Funktion ist im globalen Scope definiert
-function multiply() {
-  return num1 * num2;
-}
-
-multiply(); // gibt 60 zurück
-
-// Ein Beispiel für verschachtelte Funktionen
-function getScore() {
-  var num1 = 2,
-      num2 = 3;
-
-  function add() {
-    return name + ' scored ' + (num1 + num2);
-  }
-
-  return add();
-}
-
-getScore(); // gibt "Chamahk scored 5" zurück
-
- -

Scope und der Funktionsstack

- -

Rekursion

- -

Eine Funktion kann sich selbst referenzieren und aufrufen. Dabei gibt es drei Möglichkeiten, wie eine Funktion sich selbst referenzieren kann:

- -
    -
  1. Der Funktionsname
  2. -
  3. arguments.callee
  4. -
  5. Eine im Scope liegende Variable, die auf die Funktion referenziert.
  6. -
- -

Nimmt man zum Beispiel folgende Funktion:

- -
var foo = function bar() {
-   // Anweisungen
-};
-
- -

Folgende Anweisungen im Körper der Funktion bewirken alle das Gleiche:

- -
    -
  1. bar()
  2. -
  3. arguments.callee()
  4. -
  5. foo()
  6. -
- -

Eine Funktion, die sich selbst aufruft, wird rekursive Funktion genannt. Rekursion ist dabei vergleichbar mit einer Schleife. Beide führen den selben Quelltext mehrfach aus und beide benötigen eine Bedingung (um eine unendliche Schleife zu vermeiden oder eine unendliche Rekursion zu vermeiden). Das nächste Beispiel zeigt eine Schleife:

- -
var x = 0;
-while (x < 10) { // "x < 10" ist die Schleifenbedingung
-   // do stuff
-   x++;
-}
-
- -

Diese Schleife kann in eine rekursive Funktion konvertiert werden, die aufgerufen wird:

- -
function loop(x) {
-  if (x >= 10) // "x >= 10" ist die Abbruchbedingung (gleich zu "!(x < 10)")
-    return;
-  // do stuff
-  loop(x + 1); // der rekursive Aufruf
-}
-loop(0);
-
- -

Jedoch können manche Algorithmen nicht in eine einfache Schleife umgewandelt werden. Zum Beispiel kann das Abrufen aller Knoten einer Baumstruktur (z. B. DOM) einfacher rekursiv realisieren werden:

- -
function walkTree(node) {
-  if (node == null) //
-    return;
-  // do something with node
-  for (var i = 0; i < node.childNodes.length; i++) {
-    walkTree(node.childNodes[i]);
-  }
-}
-
- -

Verglichen mit der Funktion loop, erzeugt hier jeder rekursive Aufruf mehrere weitere rekursive Aufrufe.

- -

Es ist möglich jeden rekursiven Algorithmus in einen nicht rekursiven umzuwandeln, jedoch ist die Logik oftmals sehr viel komplexer und es wird ein zusätzlicher Stack benötigt. Rekursion nutzt ebenfalls einen Stack: den Funktionsstack.

- -

Die Stack-ähnliche Funktionsweise kann in folgendem Beispiel betrachtet werden:

- -
function foo(i) {
-  if (i < 0)
-    return;
-  console.log('begin:' + i);
-  foo(i - 1);
-  console.log('end:' + i);
-}
-foo(3);
-
-// Output:
-
-// begin: 3
-// begin: 2
-// begin: 1
-// begin: 0
-// end: 0
-// end: 1
-// end: 2
-// end: 3
- -

Verschachtelte Funktionen und Closures

- -

Man kann eine Funktion in eine andere verschachteln. Die verschachtelte (innere) Funktion ist privat innerhalb ihrer Containerfunktion (äußere Funktion). Sie formt auch eine Closure. Eine Closure ist ein Ausdruck, der freie Variablen enthalten kann, (typischerweise eine Funktion) zusammen mit einer Umgebung, welche die diese Variablen einschließt (und damit den Ausdruck abschließt, daher der Name closure).

- -

Weil eine verschachtelte Funktion eine Closure ist, bedeutet das, dass sie die Argumente und Variablen ihrer Containerfunktion vererbt bekommt. Anders gesagt enthält der Scope der inneren Funktion den Scope der äußeren Funktion.

- -

Zusammenfassend:

- - - -

Im folgenden Beispiel werden innere Funktionen gezeigt:

- -
function addSquares(a, b) {
-  function square(x) {
-    return x * x;
-  }
-  return square(a) + square(b);
-}
-a = addSquares(2, 3); // gibt 13 zurück
-b = addSquares(3, 4); // gibt 25 zurück
-c = addSquares(4, 5); // gibt 41 zurück
-
- -

Weil die innere Funktion eine Closure formt, kann die äußere Funktion aufgerufen werden und Argumente für die innere und äußere Funktion spezifizieren::

- -
function outside(x) {
-  function inside(y) {
-    return x + y;
-  }
-  return inside;
-}
-fn_inside = outside(3);  // Man kann sich das folgendermaßen vorstellen
-                         // gib mir eine Funktion, die 3 zu einem Parameter addiert.
-result = fn_inside(5);   // gibt 8 zurück
-
-result1 = outside(3)(5); // gibt 8 zurück
-
- -

Erhaltung von Variablen

- -

Bemerkenswert ist, dass x erhalten wird, wenn inside zurückgegeben wird. Eine Closure muss alle Argumente und Variablen erhalten, die sie referenziert. Weil jeder Aufruf potenziell verschiedene Argumente benötigt, wird eine neue Closure für jeden Aufruf erstellt. Der Speicher kann nur freigegeben werden, wenn die zurückgegebene inside Funktion nicht mehr erreichbar ist.

- -

Das ist nicht anders mit gespeicherten Referenzen in anderen Objekten, jedoch oftmals weniger deutlich, weil man diese nicht direkt referenziert und nicht inspizieren kann.

- -

Mehrfach verschachtelte Funktionen

- -

Funktionen können mehrfach verschachtelt sein, z. B. eine Funktion (A) enthält eine Funktion (B), die eine Funktion (C) enthält. Beide Funktionen, B und C sind Closures, B kann A erreichen und C kann B erreichen. Zudem kann C auch A erreichen, weil C B erreichen kann und B A erreichen kann. Deswegen kann eine Closure mehrere Scopes enthalten.; sie enthält rekursiv die Scopes der Funktion, die der Container ist. Das wird Scopeverkettung (scope chaining) genannt.

- -

Untersuche das nächste Beispiel:

- -
function A(x) {
-  function B(y) {
-    function C(z) {
-      console.log(x + y + z);
-    }
-    C(3);
-  }
-  B(2);
-}
-A(1); // logs 6 (1 + 2 + 3)
-
- -

In diesem Beispiel benutzt C die Variablen y, von B, und x, von A. Das kann gemacht werden weil:

- -
    -
  1. B ist eine Closure, die A enthält, z. B. B kann die Argumente und Variablen von A benutzen.
  2. -
  3. C ist ein Closure, die B enthält.
  4. -
  5. Weil die Closure von B auf A zugreifen kann, kann die Closure von C auf die Argumente und Variablen von A und B zugreifen. Anders gesagt verkettet C den Scope von B und A in dieser Reihenfolge.
  6. -
- -

Das umgekehrte ist nicht möglich. A kann nicht auf C zugreifen, weil A nicht auf die Variablen und Argumente von B zugreifen kann und C eine Variable von B ist. So bleibt C für B privat.

- -

Namenskonflikte

- -

Wenn zwei Argumente oder Variablen in dem Scope einer Closure mit dem gleichen Namen existieren, gibt es einen Namenskonflikt. Der innerste Scope hat dann Vorrang, was bedeutet, dass der innerste Scope die höchste Priorität hat, während der äußerste Scope die geringste Priorität hat. Das ist wegen der Scopeverkettung. Das erste Glied in der Kette ist der innerste Scope und das letzt Glied ist der äußerste Scope. Dieses ist im folgenden Beispiel zu sehen:

- -
function outside() {
-  var x = 10;
-  function inside(x) {
-    return x;
-  }
-  return inside;
-}
-result = outside()(20); // gibt 20 statt 10 zurück
-
- -

Der Namenskonflikt tritt beim der Anweisung return x auf und ist zwischen dem Parmeter x von inside und der Variable x von outside. Die Scopekette ist hier {inside, outside, globales Objekt}. Dabei bekommt x von inside eine höhere Priorität als das x von outside. und 20 wird statt der 10 zurückgegeben.

- -

Closures

- -

Closures sind eines der mächtigsten Funktionen von JavaScript. JavaScript unterstützt das Verschachteln von Funktionen und erlaubt der inneren Funktionen den vollen Zugriff auf alle definierten Variablen und Funktionen der äußeren Funktion (und alle anderen Variablen und Funktionen die die äußere Funktion erreichen kann). Jedoch hat die äußere Funktion keinen Zugriff auf die Variablen und Funktione, die in der innere Funktion definiert werden. Das unterstützt mehr oder weniger Sicherheit für die Variablen der inneren Funktion. Wenn die innere Funktion Zugriff auf den Scope der äußeren Funktion hat, müssen die Variablen und Funktionen der äußeren Funktion länger leben, als die Ausführungen der inneren Funktion, weil die innere Funktion das Überleben der äußeren Funktion managet. Eine Closure wird erstellt, wenn die innere Funktion irgendwie in einem äußeren Scope der äußeren Funktion erreichbar gemacht wird.

- -
var pet = function(name) {   // Die äußere Funktion definiert eine Variable "name"
-  var getName = function() {
-    return name;             // Die innere Funktion hat Zugriff auf die "name" Variable der äußeren Funktion
-  }
-  return getName;            // gibt die innere Funktion zurück
-}
-myPet = pet('Vivie');
-
-myPet();                     // gibt "Vivie" zurück
-
- -

Es kann viel komplexer sein, als der oben gezeigte Quelltext. Ein Objekt enthält Methoden zum verändern von inneren Variablen der äußeren Funktion.

- -
var createPet = function(name) {
-  var sex;
-
-  return {
-    setName: function(newName) {
-      name = newName;
-    },
-
-    getName: function() {
-      return name;
-    },
-
-    getSex: function() {
-      return sex;
-    },
-
-    setSex: function(newSex) {
-      if(typeof newSex === 'string' && (newSex.toLowerCase() === 'male' || newSex.toLowerCase() === 'female')) {
-        sex = newSex;
-      }
-    }
-  }
-}
-
-var pet = createPet('Vivie');
-pet.getName();                  // Vivie
-
-pet.setName('Oliver');
-pet.setSex('male');
-pet.getSex();                   // male
-pet.getName();                  // Oliver
-
- -

Im Quelltext oben ist die name Variable der äußeren Funktion in den inneren Funktionen erreichbar und es gibt keine andere Möglichkeit die inneren Variablen zu erreichen, als über die inneren Funktion. Die innere Variable der inneren Funktion fungiert als sicherer Speicher für die äußeren Parameter und Variablen. Sie enthalten permanent und sicher die Daten mit denen die innere Funktion arbeitet. Die Funktion hat niemals eine Variable beschrieben noch hat sie einen Namen.

- -
var getCode = (function() {
-  var secureCode = '0]Eal(eh&2';    // Ein Code der nicht von Außerhalb verändert werden soll
-
-  return function () {
-    return secureCode;
-  };
-}());
-
-getCode();    // gibt secureCode zurück.
-
- -

Es gibt aber eine menge von Tücken, die der Einsatz von Closures mit sich bringt. Wenn eine innere Funktion eine Variable definiert, die den gleichen Namen wie eine Variable im äußeren Scope hat, kann die äußere Variable nicht mehr referenziert werden.

- -
var createPet = function(name) {  // Äußere Funktion definiert die Variable "name"
-  return {
-    setName: function(name) {    // Innere Funktion definiert ebenfalls eine Variable "name"
-      name = name;               // Wie referenziert man die Variable "name" der äußeren Funktion?
-    }
-  }
-}
-
- -

Einsatz des arguments Objekts

- -

Die Argumente einer Funktion werden in einem Array-ähnlichen Objekt gewartet. In einer Funktion können die Argumente wie folgt adressiert werden:

- -
arguments[i]
-
- -

i ist die Ordnungsnummer des Arguments, beginnend bei null. So ist das erste übergebene Argument einer Funktion arguments[0]. Die Anzahl der übergebenen Argumente ist arguments.length.

- -

Mit dem arguments Objekt kann man eine Funktion mit mehr Agumenten aufrufen als sie formal deklariert wurden. Das ist oft nützlich, wenn man nicht weiß, wie viele Argumente einer Funktion übergeben werden. Mit arguments.length kann die Anzahl der Argumente, die einer Funktion übergeben wurde, ermittelt werden. Über das arguments Objekt können dann alle Argumente gelesen werden.

- -

Zum Beispiel kann es eine Funktion geben, die verschieden viele Strings zusammenfügt. Das einzige formale Argument der Funktion ist das Trennzeichen, welches die Zeichen definiert, die zwischen den Strings eingefügt werden. Im folgenden Quelltext ist die Funktion implementiert:

- -
function myConcat(separator) {
-   var result = ''; // initialize list
-   var i;
-   // iterate through arguments
-   for (i = 1; i < arguments.length; i++) {
-      result += arguments[i] + separator;
-   }
-   return result;
-}
-
- -

Man kann der Funktion jede Anzahl an Argumenten übergeben und die Funktion fügt die Argumente in einem String zusammen:

- -
// returns "red, orange, blue, "
-myConcat(', ', 'red', 'orange', 'blue');
-
-// returns "elephant; giraffe; lion; cheetah; "
-myConcat('; ', 'elephant', 'giraffe', 'lion', 'cheetah');
-
-// returns "sage. basil. oregano. pepper. parsley. "
-myConcat('. ', 'sage', 'basil', 'oregano', 'pepper', 'parsley');
-
- -
-

Hinweis: Die arguments Variable ist "Array-ähnlich", aber kein Array. Es ist Array-ähnlich indem es nummerierte Indizes und eine length Eigenschaft hat. Jedoch unterstützt es nicht alle Array-Manipulations-Methoden.

-
- -

Siehe im {{jsxref("Function")}} Objekt in den JavaScript Referenzen für mehr Informationen.

- -

Funktionsparameter

- -

Mit ECMAScript 2015, gibt es zwei neue Arten von Parametern: Default-Parameter und Rest-Parameter.

- -

Default-Parameter

- -

In JavaScript ist der Standardwert eines Parameters undefined. In manchen Situationen ist es sinnvoll den Standardwert auf einen anderen Wert zu setzen. Das ist das Einsatzgebiet von Default-Parametern.

- -

In der Vergangenheit war die Strategie für das Setzen von Standardwerten, dass im Körper der Funktion geprüft wird, ob ein Parameter undefined ist und ihn in diesem Fall neu zu beschreiben. Wenn im folgenden Beispiel kein Argument b übergeben wird, wird dieser undefined sein und die Auswertung von a*b wird NaN sein. Deswegen ist dieser Fall in der zweiten Zeile des Beispiels abgefangen:

- -
function multiply(a, b) {
-  b = typeof b !== 'undefined' ?  b : 1;
-
-  return a * b;
-}
-
-multiply(5); // 5
-
- -

Mit Default-Parametern ist die Überprüfung im Körper der Funktion nicht mehr nötig. Jetzt kann man 1 als Standardwert für b im Funktionskopf angeben:

- -
function multiply(a, b = 1) {
-  return a * b;
-}
-
-multiply(5); // 5
- -

Für mehr Details, siehe in den Referenzen unter Default-Parameter.

- -

Rest-Parameter

- -

Die Rest-Parameter Syntax ermöglicht er eine unendliche Anzahl von Argumenten als Array zu repräsentieren. Im Beispiel wird der Rest-Parameter eingesetzt um die alle Argumente ab dem zweiten Argument zu sammeln. Danach werden diese mit dem ersten Parameter multipliziert. Dieses Beispiel benutzt Pfeilfunktionen, welche in nächsten Kapitel erklärt werden:

- -
function multiply(multiplier, ...theArgs) {
-  return theArgs.map(x => multiplier * x);
-}
-
-var arr = multiply(2, 1, 2, 3);
-console.log(arr); // [2, 4, 6]
- -

Pfeilfunktionen

- -

Ein Pfeilfunktions Ausdruck hat eine kürzere Syntax verglichen mit Funktionsausdrücken und bindet lexikalisch den this Wert. Pfeilfunktionen sind immer anonym. Sie dazu auch den hacks.mozilla.org Blogbeitrag: "ES6 In Depth: Arrow functions".

- -

Zwei Faktoren haben die Einführung von Pfeilfunktionen beeinflusst: kürzere Funktionen und lexikalisches this.

- -

Kürzere Funktionen

- -

In manchen funktionalen Patterns sind kurze Funktionen willkommen. Vergleiche:

- -
var a = [
-  'Hydrogen',
-  'Helium',
-  'Lithium',
-  'Beryl­lium'
-];
-
-var a2 = a.map(function(s) { return s.length; });
-
-console.log(a2); // logs [8, 6, 7, 9]
-
-var a3 = a.map( s => s.length );
-
-console.log(a3); // logs [8, 6, 7, 9]
-
- -

Lexikalisches this

- -

Bis es Pfeilfunktionen gab, hat jede neue Funktion sein eigenen this Wert definiert (ein neues Objekt in Fällen eines Konstruktors, undefined in Funktionsaufrufen im strict mode, das Kontextobjekt, wenn eine Funktion als Objektmethode aufgerufen wird, etc.). Das ist lästig mit objektorientierten Programmierstilen.

- -
function Person() {
-  // The Person() constructor defines `this` as itself.
-  this.age = 0;
-
-  setInterval(function growUp() {
-    // In nonstrict mode, the growUp() function defines `this`
-    // as the global object, which is different from the `this`
-    // defined by the Person() constructor.
-    this.age++;
-  }, 1000);
-}
-
-var p = new Person();
- -

In ECMAScript 3/5, wurde dieses Problem behoben, indem der Wert der Variablen this in einer weiteren Variablen gespeichert wird.

- -
function Person() {
-  var self = this; // Some choose `that` instead of `self`.
-                   // Choose one and be consistent.
-  self.age = 0;
-
-  setInterval(function growUp() {
-    // The callback refers to the `self` variable of which
-    // the value is the expected object.
-    self.age++;
-  }, 1000);
-}
- -

Alternativ kann eine gebundene Funktion  erstellt werden, so dass der Wert für this mit übergeben werden kann.

- -

Pfeilfunktionen nutzen den this Wert des umschließenden Kontextes, so dass der folgende Quelltext wie erwartet funktioniert:

- -
function Person() {
-  this.age = 0;
-
-  setInterval(() => {
-    this.age++; // |this| properly refers to the person object
-  }, 1000);
-}
-
-var p = new Person();
- -

Vordefinierte Funktionen

- -

JavaScript hat einige eingebaute Funktionen:

- -
-
{{jsxref("Global_Objects/eval", "eval()")}}
-
-

Die eval() Methode wertet JavaScript Quelltext repräsentiert als String aus.

-
-
{{jsxref("Global_Objects/uneval", "uneval()")}} {{non-standard_inline}}
-
-

Die uneval() Methode erstellt einen String der Quelltext eines {{jsxref("Object")}}s repräsentiert.

-
-
{{jsxref("Global_Objects/isFinite", "isFinite()")}}
-
-

Die globale isFinite() Funktion ob ein übergebener Wert endlich ist. Der übergebene Wert wird, wenn es nötig ist, zu einer Zahl konvertiert.

-
-
{{jsxref("Global_Objects/isNaN", "isNaN()")}}
-
Die isNaN() Funktion überprüft, ob ein Wert {{jsxref("Global_Objects/NaN", "NaN")}} ist oder nicht. Hinweis: Wegen einigen Zwängen innerhalb der isNaN Funktion gibt es interessante Regeln; alternativ kann auch die in  ECMAScript 2015 definierte Funktion Funktion {{jsxref("Number.isNaN()")}} oder der Operator typeof verwendet werden, um einen {{jsxref("Global_Objects/NaN", "NaN")}} Wert zu erkennen.
-
{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}
-
-

Doe parseFloat() Funktion liest einen String als Argument ein und gibt eine Gleitkommazahl zurück.

-
-
{{jsxref("Global_Objects/parseInt", "parseInt()")}}
-
-

Die parseInt() Funktion liest einen String als Argument ein und gibt eine ganze Zahl der Spezifizierten Basis zurück (die Basis ist in der Mathematik das Zahlensystem).

-
-
{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}
-
-

Die decodeURI() Methode decodiert einen Uniform Resource Identifier (URI), der vorher mit der {{jsxref("Global_Objects/encodeURI", "encodeURI")}} Funktion order einer ähnlichen Funktion erstellt wurde.

-
-
{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}
-
-

Die decodeURIComponent() Methode decodiert eine Uniform Resource Identifier (URI) Komponente, die vorher mit der {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} Funktion oder einer ähnlichen Funktion erstellt wurde.

-
-
{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}
-
-

Die encodeURI() Methode codiert einen Uniform Resource Identifier (URI), indem jedes besondere Zeilen durch eine Sequenz aus zwei drei oder vier Zeichen escaped wird. Dieses Sequenzen Repräsentieren die UTF-8 Darstellung der Zeichen (wird nur vier escape Sequenzen von Zeichen zu zwei zwei Platzhalterzeichen umwandeln)

-
-
{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}
-
-

Die encodeURIComponent() Methode codiert eine Uniform Resource Identifier (URI) Komponente, indem jedes besondere Zeilen durch eine Sequenz aus zwei drei oder vier Zeichen escaped wird. Dieses Sequenzen Repräsentieren die UTF-8 Darstellung der Zeichen (wird nur vier escape Sequenzen von Zeichen zu zwei zwei Platzhalterzeichen umwandeln)

-
-
{{jsxref("Global_Objects/escape", "escape()")}} {{deprecated_inline}}
-
-

Die veraltete escape() Methode berechnet einen neuen String indem manche Zeichen durch Hexadezimalsequenzen ersetzt werden. Man sollte {{jsxref("Global_Objects/encodeURI", "encodeURI")}} oder {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} stattdessen benutzen.

-
-
{{jsxref("Global_Objects/unescape", "unescape()")}} {{deprecated_inline}}
-
-

Die veraltete unescape() Methode berechnet einen neuen String indem Hexadezimalsequenzen durch die repräsentierenden Zeichen ersetzt werden. Die Hexadezimalsequenzen können von Funktionen wie {{jsxref("Global_Objects/escape", "escape")}} eingeführt werden. Weil unescape() veraltet ist, sollte man stattdessen die Funktion {{jsxref("Global_Objects/decodeURI", "decodeURI()")}} oder {{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent")}} benutzen.

-
-
- -

{{PreviousNext("Web/JavaScript/Guide/Schleifen_und_Iterationen", "Web/JavaScript/Guide/Ausdruecke_und_Operatoren")}}

diff --git a/files/de/web/javascript/guide/grammar_and_types/index.html b/files/de/web/javascript/guide/grammar_and_types/index.html new file mode 100644 index 0000000000..3ca2b9936b --- /dev/null +++ b/files/de/web/javascript/guide/grammar_and_types/index.html @@ -0,0 +1,699 @@ +--- +title: Grammatik und Typen +slug: Web/JavaScript/Guide/Grammatik_und_Typen +tags: + - Guide + - JavaScript + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Grammar_and_types +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Einführung", "Web/JavaScript/Guide/Kontrollfluss_und_Fehlerbehandlung")}}
+ +

Dieses Kapitel behandelt die grundlegende Grammatik von JavaScript, Deklaration von Variablen, Datentypen und Objektinstanzen.

+ +

Grundlagen

+ +

JavaScript leiht sich den größten Teil seiner Syntax von Java, ist aber auch von Sprachen wie Awk, Perl und Python beeinflusst.

+ +

JavaScript ist case-sensitiv (unterscheidet zwischen Groß- und Kleinschreibung) und benutzt den Unicode-Zeichensatz. Zum Beispiel kann das Wort Früh als Variablenname genutzt werden.

+ +
var Früh = "foobar";
+
+ +

Jedoch ist die Variable früh nicht dieselbe wie Früh, weil JavaScript case-sensitiv ist.

+ +

In JavaScript heißen Anweisungen "{{Glossary("Statement", "statements")}}" und werden durch ein Semikolon (;) voneinander getrennt. Ein Semikolon ist nicht nötig, wenn jedes Statement in einer neuen Zeile ist. Wenn mehrere Statements in einer Zeile geschrieben werden, sollte nach jedes mit einem Semikolon trennen. Zudem ist es gängige Praxis, hinter jedem Statement ein Semikolon zu schreiben. Leerzeichen, Tabulatoren und Zeilenumbrüche werden "Whitespace" genannt. Der Quelltext von JavaScript wird vom Interpreter von links nach rechts gelesen und in Sequenzen von Eingabe-Elementen wie JavaScript-Tokens, Steuerzeichen, Zeichenumbrüche, Kommentare und Objektinstanzen (Literale) umgewandelt. ECMAScript beschreibt für den Interpreter reservierte Schlüsselwörter sowie Objektinstanzen und hat eingebaute Regeln für die automatische Einfügung von Semikola (ASI) um Anweisungen zu beenden. Es wird jedoch empfohlen jede Anweisung mit einem Semikolon zu beenden; dies vermeidet ungewollte Nebeneffekte. Mehr Informationen dazu sind in der detaillierten Referenz über JavaScripts lexikalische Grammatik zu finden.

+ +

Kommentare

+ +

Die Syntax von Kommentaren ist dieselbe wie in C++ und in vielen anderen Sprachen:

+ +
// Einzeiliger Kommentar
+
+/* Das ist ein langer,
+ * mehrzeiliger Kommentar
+ */
+
+/* Man kann keine Kommentare, /* Verschachteln */ SyntaxError */
+ +

Kommentare sind wie Whitespaces und werden bei der Ausführung von Skripten verworfen.

+ +

Deklarationen

+ +

Es gibt drei mögliche Arten, Variablen zu deklarieren:

+ +
+
{{jsxref("Statements/var", "var")}}
+
Deklariert eine Variable. Optional wird ein Wert initialisiert.
+
{{jsxref("Statements/let", "let")}}
+
Deklariert eine Variable mit Gültigkeit im aktuellen Block. Optional wird ein Wert initialisiert.
+
{{jsxref("Statements/const", "const")}}
+
Deklariert eine Konstante mit Gültigkeit im aktuellen Block.
+
+ +

Variablen

+ +

Variablen werden benutzt, um Werte zu speichern. Dabei gibt man einer Variablen einen Namen, der {{Glossary("identifier", "Bezeichner")}} bzw. Bezeichner genannt wird und der bestimmten Regeln folgt.

+ +

Ein JavaScript Bezeichner muss mit einem Buchstaben, Unterstrich (_) oder einem Dollarzeichen ($) beginnen. Die nachfolgenden Zeichen können auch Zahlen sein. Da JavaScript case-sensitive ist, wird zwischen Groß- und Kleinschreibung unterschieden und somit repräsentiert "A" einen anderen Buchstaben als "a".

+ +

Es kann ein Großteil der ISO 8859-1 und Unicode-Zeichen benutzt werden, wie z.B. ü oder auch å, aber auch Unicode escape sequences können genutzt werden.

+ +

Beispiele für zulässige Bezeichner sind Number_hits, temp99 und _name.

+ +

Variablendeklaration

+ +

Die Deklaration einer Variable ist durch drei unterschiedliche Wege möglich:

+ + + +

Variablen auswerten

+ +

Eine Variable, die mit var ohne Initialisierung deklariert wurde, hat den Wert {{jsxref("undefined")}}.

+ +

Der Zugriff auf eine nicht initialisierte Variable und der Zugriff auf eine let-Variable, bevor diese Initialisiert wurde, erzeugt einen {{jsxref("ReferenceError")}} Fehler:

+ +
var a;
+console.log("Der Wert von a ist " + a); // Der Wert von a ist undefined
+
+console.log("Der Wert von b ist " + b); // Der Wert von b ist undefined
+var b;
+
+console.log("Der Wert von c ist " + c); // ReferenceError: c is not defined
+
+let x
+console.log("Der Wert von x ist " + x); // Der Wert von x ist undefined
+
+console.log("Der Wert von y ist " + y); // ReferenceError: y is not defined
+let y;
+
+ +

undefined kann benutzt werden, um zu überprüfen ob eine Variable einen Wert hat. Im Folgenden Codebeispiel ist der Variable input kein Wert zugewiesen worden und das if-Statement wird somit true ausgeben.

+ +
var input;
+if(input === undefined){
+  macheDas();
+} else {
+  macheDasAndere();
+}
+
+ +

undefined verhält sich wie ein false, wenn es in einem boolschen Kontext verwendet wird. Zum Beispiel wird im folgendem Codebeispiel die Funktion myFunction ausgeführt, weil das myArray Element undefined ist:

+ +
var myArray = [];
+if (!myArray[0]) myFunction();
+
+ +

undefined wird zu NaN (Not a Number) konvertiert, wenn es in einem numerischen Kontext verwendet wird:

+ +
var a;
+a + 2;  //NaN
+ +

Wenn eine {{jsxref("null")}} Variable ausgewertet wird, verhält sie sich im numerischen Kontext wie 0 und in booleschem Kontext wie false:

+ +
var n = null;
+console.log(n * 32);  // wird 0 in die Konsole eintragen
+
+ +

Variablen Scope

+ +

Wird eine Variable außerhalb eines Code-Blocks deklariert, wird sie eine globale Variable genannt, da sie jetzt in jedem Bereich verfügbar ist. Wenn eine Variable jedoch innerhalb eines Code-Blocks deklariert wird, so ist sie nur innerhalb dieses Blocks verfügbar und wird aus diesem Grund lokale Variable genannt.

+ +

JavaScript hatte vor ECMAScript 2015 keinen Block-Anweisungs Scope; daher wurde eine deklarierte Variable in einem Block immer zu der Funktion (oder dem globalen Scope) gezählt, in dem sich der Block befand. Zum Beispiel wird der folgende Quelltext 5 ausgeben, weil der Scope von x die Funktion ist bzw. der globale Kontext, in dem x deklariert wurde, und nicht der Block, in diesem Fall die if Anweisung, selbst.

+ +
if (true) {
+  var x = 5;
+}
+console.log(x);  // 5
+
+ +

Das Verhalten ändert sich, wenn man die in ECMAScript 2015 eingeführte let Deklaration benutzt.

+ +
if (true) {
+  let y = 5;
+}
+console.log(y);  // ReferenceError: y is not defined
+
+ +

Variablen hochziehen (hoisting)

+ +

Eine andere Besonderheit mit Variablen in JavaScript ist, dass man eine Variable referenzieren kann, bevor sie deklariert wurde, ohne das es zu einem Fehler kommt. Diese Konzept ist bekannt als hoisting (hochziehen); Variablen in JavaScript sind hochgezogen und quasi zum Anfang der Funktion oder des Statements gehoben worden. Immer wenn Variablen hochgezogen werden, werden sie den Wert undefined zurückgeben. So wird immer undefined zurückgegeben, wenn man die Variablen benutzt, bevor sie deklariert und initialisiert wurden.

+ +
/**
+ * Beispiel 1
+ */
+console.log(x === undefined); // true
+var x = 3;
+
+/**
+ * Beispiel 2
+ * wird den Wert undefined zurückgeben
+ */
+var myvar = "my value";
+
+(function() {
+  console.log(myvar); // undefined
+  var myvar = "local value";
+})();
+
+ +

Das obere Beispiel wird genauso interpretiert, wie das folgende Beispiel:

+ +
/**
+ * Beispiel 1
+ */
+var x;
+console.log(x === undefined); // true
+x = 3;
+
+/**
+ * Beispiel 2
+ */
+var myvar = "my value";
+
+(function() {
+  var myvar;
+  console.log(myvar); // undefined
+  myvar = "local value";
+})();
+
+ +

Wegen des Hochziehens sollten alle var Anweisungen so weit am Anfang der Funktion wie nur möglich platziert werden. Dieses Vorgehen verbessert die Qualität des Quelltextes.

+ +

In ECMAScript 2015 wird let (bzw. const) nicht an den Anfang eines Blocks hochgezogen. Das Referenzieren der Variable in dem Block, bevor diese deklariert wurde, führt zu einem {{jsxref("ReferenceError")}}. Die Variable ist in einer "temporären toten Zone", die vom Start des Blocks bis zur Deklaration der Variablen besteht.

+ +
console.log(x); // ReferenceError
+let x = 3;
+ +

Funktionen hochziehen (hoisting)

+ +

Bei Funktionen (nur Funktionsdeklarationen) werden die Deklarationen ebenfalls nach oben gezogen. Bei Funktionsausdrücken gilt das jedoch nicht.

+ +
/* Funktionsdeklaration */
+
+foo(); // "bar"
+
+function foo() {
+   console.log("bar");
+}
+
+
+/* Funktionsausdruck */
+
+baz(); // TypeError: baz ist keine Funktion
+
+var baz = function() {
+   console.log("bar2");
+};
+
+ +

Globale Variablen

+ +

Globale Variablen sind faktisch Eigenschaften des globalen Objekts. In Webseiten ist das globale Objekt das {{domxref("window")}} Objekt, so dass globale Variablen gesetzt und erreicht werden können, indem die Syntax window.variable eingesetzt wird.

+ +

Folglich kann man globale Variablen, die in einem window oder frame deklariert wurden, aus einem anderen window oder Frame erreichen, indem der window oder framename angegeben wird. Zum Beispiel kann eine Variable phoneNumber, die in einem Dokument deklariert wurde, von einem iframe mit parent.phoneNumber erreicht werden.

+ +

Konstanten

+ +

Man kann eine nur lesende, benannte Konstante mit dem Schlüsselwort {{jsxref("Statements/const", "const")}} erstellen. Die Syntax für einen Konstantenbezeichner ist dieselbe, wie für Variablenbezeichner: Er muss mit einem Buchstaben, Unterstrich oder Dollarzeichen beginnen und kann alphabetische Zeichen, numerische Zeichen und Unterstriche enthalten.

+ +
const PI = 3.14;
+
+ +

Der Wert einer Konstanten kann nicht zur Laufzeit durch Zuweisungen oder Neudeklarationen geändert werden. Konstanten müssen deswegen immer initialisiert werden.

+ +

Die Sichtbarkeitsregeln (Scope) bei Konstanten sind die gleichen, wie für let Blockscope Variablen. Wenn das Schüsselwort const weggelassen wird, wird vorausgesetzt, dass der Bezeichner eine Variable repräsentiert.

+ +

Man kann keine Konstante mit dem gleichen Namen einer Funktion oder Variablen im gleiche Gültigkeitsbereich deklarieren. Zum Beispiel:

+ +
// DAS WIRD ZU EINEM ERROR FÜHREN
+function f() {};
+const f = 5;
+
+// DAS WIRD EBENFALLS ZU EINEM ERROR FÜHREN
+function f() {
+  const g = 5;
+  var g;
+
+  //statements
+}
+
+ +

Immer, wenn Objektattribute nicht geschützt sind, werden die folgenden Anweisungen ohne Probleme ausgeführt.

+ +
const MY_OBJECT = {"key": "value"};
+MY_OBJECT.key = "otherValue";
+ +

Jedoch ist der Inhalt eines Arrays nicht geschützt, sodass folgendes Statement ohne Probleme ausgeführt wird.

+ +
const MY_ARRAY = ['HTML','CSS'];
+MY_ARRAY.push('JAVASCRIPT');
+console.log(MY_ARRAY); // logs ['HTML','CSS','JAVASCRIPT']
+
+ +

Datenstrukturen und -typen

+ +

Datentypen

+ +

Der neuste ECMAScript Standard definiert sieben Datentypen:

+ + + +

Obwohl die Anzahl der Datentypen relativ klein ist, eröffnen sie die Möglichkeit nützliche Funktionen für Applikationen zu erstellen. {{jsxref("Object", "Objects")}} und {{jsxref("Function", "functions")}} sind die anderen fundamentalen Elemente der Sprache. Man kann sich Objekte als benannte Container für Werte und Funktionen, die die Applikation ausführen kann, vorstellen.

+ +

Datentypkonvertierungen

+ +

JavaScript ist eine dynamisch typisierte Sprache. Das bedeutet, dass man den Datentypen einer Variable bei der Deklaration nicht mit angibt. Der Datentyp wird während der Ausführung automatisch konvertiert, wenn es notwendig ist. So kann eine Variable folgendermaßen definiert werden:

+ +
var answer = 42;
+
+ +

Und Später kann der gleichen Variablen eine Zeichenkette zugewiesen werden:

+ +
answer = "Thanks for all the fish...";
+
+ +

Weil JavaScript dynamisch typisiert ist, erzeugt diese Zuweisung keinen Fehler im Programm.

+ +

In Ausdrücken, in denen Zahlen und Zeichenketten mit dem + Operator gebraucht werden, konvertiert JavaScript die Zahlen in Zeichenketten. Siehe dazu das folgende Beispiel:

+ +
x = "The answer is " + 42 // "The answer is 42"
+y = 42 + " is the answer" // "42 is the answer"
+
+ +

In Ausdrücken mit anderen Operatoren, konvertiert JavaScript zahlen nicht in Zeichenketten. Zum Beispiel:

+ +
"37" - 7 // 30
+"37" + 7 // "377"
+
+ +

Konvertieren von Zeichenketten zu Zahlen

+ +

In Fällen, in denen eine Zahl durch einen String repräsentiert wird, gibt es folgende Methoden, um die Zeichenkette in eine Zahl umzuwandeln.

+ + + +

parseInt gibt nur ganze Zahlen zurück, weshalb der Einsatz für Dezimalzahlen nicht geeignet ist. Zu einem guten Programmierstil gehört es, dass man immer die Basis bei parseInt mit angibt. Der radix Parameter der Methode gibt an, aus welchem Zahlensystem die Zahl stammt.

+ +

Eine alternative Methode, um einen String in eine Zahl zu konvertieren ist der + (unär Plus) Operator:

+ +
"1.1" + "1.1" // "1.11.1"
+(+"1.1") + (+"1.1") // 2.2
+// Hinweis: die hinzugefügten Klammern sind nur für die Lesbarkeit.
+ +

Literale

+ +

Man benutzt Literale, um in JavaScript Werte zu repräsentieren. Es sind feste Werte, keine Variablen, die man in einem Skript einsetzt. Dieses Kapitel beschreibt die folgeden Literaltypen:

+ + + +

Array Literal

+ +

Ein Array Literal ist eine Liste von null oder mehr Ausdrücken. Jeder Ausdruck repräsentiert ein Element des Arrays. Diese Elemente sind von eckigen Klammern ([]) umschlossen. Wenn ein Array mit einem Array Literal erstellt wird, wird das Array mit allen definierten Elementen initialisiert und die länge des Arrays wird auf die Menge der Elemente gesetzt.

+ +

Das folgende Beispiel erstellt das coffees Array mit drei Elementen und der Länge drei:

+ +
var coffees = ["French Roast", "Colombian", "Kona"];
+
+ +
+

Hinweis: Ein Array Literal ist eine Art von Objektinitialisierung. Sie dazu auch den Einsatz von Objektinitialisierern.

+
+ +

Wenn ein Array durch ein Literal im Toplevel Skript erstellt wird, interpretiert JavaScript das Array immer dann, wenn ein Ausdruck dieses Literal enthält. Im Gegensatz dazu wird ein Literal in einer Funktion immer neu erstellt, wenn die Funktion aufgerufen wird.

+ +

Array Literale sind ebenfalls Array Objekte. Für mehr Details siehe {{jsxref("Array")}} und Indexed collections.

+ +

Extra Kommas in Array Literalen

+ +

Man muss nicht alle Elemente in einem Array Literal spezifizieren. Wenn man zwei Kommas in einer Reihe verwendet, wird das Array mit einem undefined Element erstellt. Das folgende Beispiel erstellt das fish Array:

+ +
var fish = ["Lion", , "Angel"];
+
+ +

Dieses Array hat zwei Elemente mit Werten und ein leeres Element (fish[0] ist "Lion", fish[1] ist undefined und fish[2] ist "Angel").

+ +

Wenn man ein trennendes Komma am Ende der Elementliste hinzufügt, wird es ignoriert. Im folgenden Beispiel ist die Länge des Arrays drei. Es gibt kein myList[3]. Alle weiteren Kommas in der Liste führen zu einem neuen Element.

+ +
+

Hinweis: Trennende Kommas können in älteren Browserversionen zu Fehlern führen. Zudem ist es ein guter Stil diese Kommas zu entfernen.

+
+ +
var myList = ['home', , 'school', ];
+
+ +

Im folgenden Beispiel hat das Array vier Elemente und myList[0] und myList[2] sind nicht spezifiziert.

+ +
var myList = [ , 'home', , 'school'];
+
+ +

Im folgenden Beispiel hat das Array vier Elemente und myList[1] und myList[3] sind nicht spezifiziert. Nur das letzte Komma wird ignoriert.

+ +
var myList = ['home', , 'school', , ];
+
+ +

Das Verständnis für das Verhalten von extra Kommas ist wichtig, um JavaScript als Sprache zu verstehen. Immer, wenn man seinen eigenen Quelltext schreibt, sollten explizit fehlenden Elementen mit undefined deklariert werden, damit die Lesbarkeit und Wartbarkeit des Quelltextes besser ist.

+ +

Boolean Literale

+ +

Der Boolean Typ hat zwei Literale: true und false.

+ +

Man sollte die primitiven Werte true und false jedoch nicht mit den Werten true und false des Boolean Objektes verwechseln. Das Boolean Objekt ist eine Hülle um den primitiven Boolean Datentypen. Siehe im Artikel {{jsxref("Boolean")}} für weitere Informationen.

+ +

Numerische Literale

+ +

Ganze Zahlen können als Dezimal- (Basis 10), Hexadezimal- (Basis 16), Oktal- (Basis 8) und Binärzahl (Basis 2) ausgedrückt werden.

+ + + +

Im folgenden Beispiel sind einige Beispiele für Zahlenliterale:

+ +
0, 117 und -345 (dezimal, Basis 10)
+015, 0001 und -0o77 (oktal, Basis 8)
+0x1123, 0x00111 und -0xF1A7 (hexadezimal, "hex", Base 16)
+0b11, 0b0011 und -0b11 (binär, Basis 2)
+
+ +

Für weitere Informationen siehe numerische Literale in der Lexikalischen Grammatik Referenz.

+ +

Gleitkomma Literale

+ +

Ein Gleitkomma Literal kann die folgenden Abschnitte beinhalten:

+ + + +

Der Exponent besteht aus einem "e" oder "E" gefolgt von einer ganzen Zahl, die mit einem Vorzeichen ("+" oder "-") versehen sein kann. Eine Gleitkommazahl muss mindestens aus einer Ziffer und entweder einem Dezimalpunkt oder einem "e" (oder "E") bestehen.

+ +

Kurz und knapp sieht die Syntax folgendermaßen aus:

+ +
[(+|-)][ziffern][.ziffern][(E|e)[(+|-)]ziffern]
+
+ +

Zum Beispiel:

+ +
3.1415926
+-.123456789
+-3.1E+12
+.1e-23
+
+ +

Objekt Literale

+ +

Ein Objekt Literal ist eine Liste von null oder mehr Paaren von Eigenschaftsnamen und -werten, umschlossen von geschweiften Klammern ({}). Man sollte kein Objektliteral am Anfang eines Statements benutzen. Das wird zu einem Fehler führen oder nicht wie erwartet funktionieren, weil das {-Zeichen als Anfang eines Blocks interpretiert wird.

+ +

Es folgt ein Beispiel für ein Objekt Literal. Das erste Element des car Objektes definiert eine Eigenschaft myCar und beschreibt diese mit einem neuen String "Saturn". Am zweiten Element, der getCar Eigenschaft, wird der Rückgabewert der aufgerufenen Funktion carTypes("Honda") zugewiesen. Das dritte Element, die special Eigenschaft, benutzt eine existierende Variable sales.

+ +
var sales = "Toyota";
+
+function carTypes(name) {
+  if (name === "Honda") {
+    return name;
+  } else {
+    return "Sorry, we don't sell " + name + ".";
+  }
+}
+
+var car = {
+  myCar: "Saturn",
+  getCar: carTypes("Honda"),
+  special: sales
+};
+
+console.log(car.myCar);   // Saturn
+console.log(car.getCar);  // Honda
+console.log(car.special); // Toyota
+
+ +

Für die Namen der Eigenschaften kann auch ein String oder ein Zahlen Literal verwendet werden. Für den Wert kann auch ein verschachteltes Objekt Literal genutzt werden. Das folgende Beispiel nutzt diese Optionen.

+ +
var car = { manyCars: {a: 'Saab', b: 'Jeep'}, 7: 'Mazda' };
+
+console.log(car.manyCars.b); // Jeep
+console.log(car[7]); // Mazda
+
+ +

Die Namen von Objekteigenschaften können ein String sein, was auch den leeren String beinhaltet. Wenn die Eigenschaftsnamen keine gültigen JavaScript {{Glossary("Identifier","Bezeichner")}} sind, müssen sie in Anführungszeichen geschrieben werden. Eigenschaftsnamen die keine gültigen Bezeichner sind, können nicht mit der Punktschreibweise (.) erreicht werden. Wohl aber mit der Array ähnlichen Notation ("[]").

+ +
var unusualPropertyNames = {
+  "": "An empty string",
+  "!": "Bang!"
+}
+console.log(unusualPropertyNames."");   // SyntaxError: Unexpected string
+console.log(unusualPropertyNames[""]);  // An empty string
+console.log(unusualPropertyNames.!);    // SyntaxError: Unexpected token !
+console.log(unusualPropertyNames["!"]); // Bang!
+ +

Erweiterte Objekt Literale

+ +

In ES2015 wurde das Objekt Literal dahingehend erweitert, dass der Prototyp bei der Erstellung gesetzt wird. Desweiteren sind neue Funktionalitäten hinzugekommen, die eine Kurzschreibweise für foo: foo Zuweisungen, die Definitionen für Methoden, das Aufrufen von super Methoden und die Berechnung der Eigenschaftsnamen mit Ausdrücken ermöglichen. Alle diese Funktionen bringen zum Einen Klassendefinition und Objekt Literale näher zusammen und sind somit objektbasiertes Design und zum Anderen häufig vorteilhafter und bequemer.

+ +
var obj = {
+    // __proto__
+    __proto__: theProtoObj,
+    // Shorthand for ‘handler: handler’
+    handler,
+    // Methods
+    toString() {
+     // Super calls
+     return "d " + super.toString();
+    },
+    // Computed (dynamic) property names
+    [ 'prop_' + (() => 42)() ]: 42
+};
+ +

Bitte beachten:

+ +
var foo = {a: "alpha", 2: "two"};
+console.log(foo.a);    // alpha
+console.log(foo[2]);   // two
+//console.log(foo.2);  // Error: missing ) after argument list
+//console.log(foo[a]); // Error: a is not defined
+console.log(foo["a"]); // alpha
+console.log(foo["2"]); // two
+
+ +

RegExp Literale

+ +

Ein RegExp Literal (welcher im Detail später erklärt wird) ist ein Pattern (Muster) umschlossen von Slashes (/). Das Folgende ist ein Beispiel für ein RegExp Literal:

+ +
var re = /ab+c/;
+ +

String Literale

+ +

Ein String Literal besteht aus null oder mehr Zeichen, die von doppelten (") oder einfachen (') Anführungszeichen umschlossen sind. Ein String muss immer von gleichen Anführungszeichen umschlossen sein. Entweder von einfachen oder von doppelten Anführungszeichen. Im folgenden Beispiel sind ein paar String Literale gezeigt:

+ +
"foo"
+'bar'
+"1234"
+"eine Zeile \n weitere Zeile"
+"John's cat"
+
+ +

Man kann alle Methoden des String Objektes auf einem String Literal aufrufen, denn JavaScript konvertiert das Literal automatisch in ein temporäres String Objekt, führt die Methode aus und verwirft danach das temporäre Objekt. Man kann auch die String.length Eigenschaft mit einem String Literal benutzen:

+ +
console.log("John's cat".length)
+// Wird die Anzahl der Zeichen (auch Leerzeichen) ausgeben.
+// In diesem Fall 10.
+
+ +

In ES2015, wurden zudem Template Literale eingeführt. Template Literale sind von Backticks (` `) (Gravis) umschlossen. Template Strings bieten syntaktischen Zucker für das Erstellen von Strings an. Sie sind vergleichbar mit den String Interpolations Funktionen in Perl, Python und anderen Sprachen. Optional können Marken eingefügt werden, um einen String benutzerdefiniert zu erstellen. Sie vermeiden Injection-Attacken und ermöglichen es Datenstrukturen in Strings unterzubringen.

+ +
// Standardliteral für die String erstellung
+`In JavaScript '\n' is a line-feed.`
+
+// Mehrzellige Strings
+`In JavaScript ist das
+ nicht erlaubt.`
+
+// String Interpolation
+var name = "Bob", time = "today";
+`Hello ${name}, how are you ${time}?`
+
+// Erstellung einer HTTP Anfrage.
+POST`http://foo.org/bar?a=${a}&b=${b}
+     Content-Type: application/json
+     X-Credentials: ${credentials}
+     { "foo": ${foo},
+       "bar": ${bar}}`(myOnReadyStateChangeHandler);
+ +

Man sollte String Literale benutzen, sofern man nicht explizit ein Objekt benötigt. Für weitere Informationen siehe im {{jsxref("String")}} Artikel nach.

+ +

Einsatz von Sonderzeichen in Strings

+ +

Neben den normalen Zeichen ist es auch möglich Sonderzeichen in einem String zu verwenden. Ein Beispiel ist im folgenden zu sehen:

+ +
"eine Zeile \n nächste Zeile"
+
+ +

Die folgende Tabelle Zeigt die Sonderzeichen, die in JavaScript Strings verwendet werden können:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table: JavaScript Sonderzeichen
ZeichenBedeutung
\0Null Byte
\bBackspace
\fForm feed
\nNew line
\rCarriage return
\tTab
\vVertical tab
\'Einfache Anführungszeichen
\"Doppelte Anführungszeichen
\\Backslash Zeichen
\XXXDas Zeichen, das im Latin-1 Encoding mit drei Oktalzahlen (XXX) Spezifiziert wird (0 bis 377). Zum Beispiel ist \251 die Oktalsequenz für das Copyrightsymbol.
\xXXZeichen, die im Latin-1 Encoding mit zwei Hexadezimalzahlen (XX) spezifiziert werden (00 bis FF). Zum Beispiel ist \xA9 die Hexadezimalsequenz für das Copyrightsymbol.
\uXXXXDie Unicode Zeichen, die mit vier Hexadezimalziffern XXXX beschreiben werden. Zum Beispiel ist \u00A9 die Hexadezimalsequenz für das Copyrightsymbol. Siehe Unicode escape Sequenzen.
\u{XXXXX}Unicode code point escapes. Zum Beispiel ist \u{2F804} das gleiche wie das einfache Unicodezeichen \uD87E\uDC04.
+ +

Escaping Zeichen

+ +

Für nicht in der Tabelle gezeigte Zeichen wird ein voranstehendes Backslash ignoriert. Der Einsatz von Backslashs ist Veraltet und sollte vermieden werden.

+ +

Man kann Anführungszeichen in einen String hinzufügen, indem ein Führendes Backslash eingesetzt wird. Das wird auch escaping der Anführungszeichen genannt. Ein Beispiel:

+ +
var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service.";
+console.log(quote);
+
+ +

Das Ergebnis ist:

+ +
He read "The Cremation of Sam McGee" by R.W. Service.
+
+ +

Um ein Backslash in einem String zu verwenden, muss dieses mit einem Backslash escaped werden. Zum Beispiel muss der Pfad c:\temp wie folgt geschrieben werden:

+ +
var home = "c:\\temp";
+
+ +

Man kann zudem Zeilenumbrüche mit einem vorangegangenen Backslash escapen. Das Backslash und der Zeilenumbruch werden aus dem String entfernt.

+ +
var str = "this string \
+is broken \
+across multiple\
+lines."
+console.log(str);   // this string is broken across multiple lines.
+
+ +

JavaScript kennt keine "heredoc" Syntax. Um eine solche zu simulieren muss am Ende jeder Zeile mit einem Zeilenumbruch (\n) ein Backslash stehen:

+ +
var poem =
+"Roses are red,\n\
+Violets are blue.\n\
+Sugar is sweet,\n\
+and so is foo."
+
+ +

ECMAScript 2015 führte einen neuen Literaltyp, das Template Literal, ein. Dieses führte, für viele neue Funktionen, Strings mit mehrere Zeilen ein!

+ +
var poem =
+`Roses are red,
+Violets are blue.
+Sugar is sweet,
+and so is foo.`
+
+ +

Mehr Informationen

+ +

Dieses Kapitel beschränkt sich auf die Basissyntax für Deklarationen und Typen. Um mehr über die Sprachkonstrukte von JavaScript zu lernen siehe in die folgenden Kapitel dieses Guides:

+ + + +

Im nächsten Kapitel wird ein Blick auf Kontrollflüsse und Fehlerbehandlungen geworfen.

+ +

{{PreviousNext("Web/JavaScript/Guide/Einführung", "Web/JavaScript/Guide/Kontrollfluss_und_Fehlerbehandlung")}}

diff --git a/files/de/web/javascript/guide/grammatik_und_typen/index.html b/files/de/web/javascript/guide/grammatik_und_typen/index.html deleted file mode 100644 index 3ca2b9936b..0000000000 --- a/files/de/web/javascript/guide/grammatik_und_typen/index.html +++ /dev/null @@ -1,699 +0,0 @@ ---- -title: Grammatik und Typen -slug: Web/JavaScript/Guide/Grammatik_und_Typen -tags: - - Guide - - JavaScript - - 'l10n:priority' -translation_of: Web/JavaScript/Guide/Grammar_and_types ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Einführung", "Web/JavaScript/Guide/Kontrollfluss_und_Fehlerbehandlung")}}
- -

Dieses Kapitel behandelt die grundlegende Grammatik von JavaScript, Deklaration von Variablen, Datentypen und Objektinstanzen.

- -

Grundlagen

- -

JavaScript leiht sich den größten Teil seiner Syntax von Java, ist aber auch von Sprachen wie Awk, Perl und Python beeinflusst.

- -

JavaScript ist case-sensitiv (unterscheidet zwischen Groß- und Kleinschreibung) und benutzt den Unicode-Zeichensatz. Zum Beispiel kann das Wort Früh als Variablenname genutzt werden.

- -
var Früh = "foobar";
-
- -

Jedoch ist die Variable früh nicht dieselbe wie Früh, weil JavaScript case-sensitiv ist.

- -

In JavaScript heißen Anweisungen "{{Glossary("Statement", "statements")}}" und werden durch ein Semikolon (;) voneinander getrennt. Ein Semikolon ist nicht nötig, wenn jedes Statement in einer neuen Zeile ist. Wenn mehrere Statements in einer Zeile geschrieben werden, sollte nach jedes mit einem Semikolon trennen. Zudem ist es gängige Praxis, hinter jedem Statement ein Semikolon zu schreiben. Leerzeichen, Tabulatoren und Zeilenumbrüche werden "Whitespace" genannt. Der Quelltext von JavaScript wird vom Interpreter von links nach rechts gelesen und in Sequenzen von Eingabe-Elementen wie JavaScript-Tokens, Steuerzeichen, Zeichenumbrüche, Kommentare und Objektinstanzen (Literale) umgewandelt. ECMAScript beschreibt für den Interpreter reservierte Schlüsselwörter sowie Objektinstanzen und hat eingebaute Regeln für die automatische Einfügung von Semikola (ASI) um Anweisungen zu beenden. Es wird jedoch empfohlen jede Anweisung mit einem Semikolon zu beenden; dies vermeidet ungewollte Nebeneffekte. Mehr Informationen dazu sind in der detaillierten Referenz über JavaScripts lexikalische Grammatik zu finden.

- -

Kommentare

- -

Die Syntax von Kommentaren ist dieselbe wie in C++ und in vielen anderen Sprachen:

- -
// Einzeiliger Kommentar
-
-/* Das ist ein langer,
- * mehrzeiliger Kommentar
- */
-
-/* Man kann keine Kommentare, /* Verschachteln */ SyntaxError */
- -

Kommentare sind wie Whitespaces und werden bei der Ausführung von Skripten verworfen.

- -

Deklarationen

- -

Es gibt drei mögliche Arten, Variablen zu deklarieren:

- -
-
{{jsxref("Statements/var", "var")}}
-
Deklariert eine Variable. Optional wird ein Wert initialisiert.
-
{{jsxref("Statements/let", "let")}}
-
Deklariert eine Variable mit Gültigkeit im aktuellen Block. Optional wird ein Wert initialisiert.
-
{{jsxref("Statements/const", "const")}}
-
Deklariert eine Konstante mit Gültigkeit im aktuellen Block.
-
- -

Variablen

- -

Variablen werden benutzt, um Werte zu speichern. Dabei gibt man einer Variablen einen Namen, der {{Glossary("identifier", "Bezeichner")}} bzw. Bezeichner genannt wird und der bestimmten Regeln folgt.

- -

Ein JavaScript Bezeichner muss mit einem Buchstaben, Unterstrich (_) oder einem Dollarzeichen ($) beginnen. Die nachfolgenden Zeichen können auch Zahlen sein. Da JavaScript case-sensitive ist, wird zwischen Groß- und Kleinschreibung unterschieden und somit repräsentiert "A" einen anderen Buchstaben als "a".

- -

Es kann ein Großteil der ISO 8859-1 und Unicode-Zeichen benutzt werden, wie z.B. ü oder auch å, aber auch Unicode escape sequences können genutzt werden.

- -

Beispiele für zulässige Bezeichner sind Number_hits, temp99 und _name.

- -

Variablendeklaration

- -

Die Deklaration einer Variable ist durch drei unterschiedliche Wege möglich:

- - - -

Variablen auswerten

- -

Eine Variable, die mit var ohne Initialisierung deklariert wurde, hat den Wert {{jsxref("undefined")}}.

- -

Der Zugriff auf eine nicht initialisierte Variable und der Zugriff auf eine let-Variable, bevor diese Initialisiert wurde, erzeugt einen {{jsxref("ReferenceError")}} Fehler:

- -
var a;
-console.log("Der Wert von a ist " + a); // Der Wert von a ist undefined
-
-console.log("Der Wert von b ist " + b); // Der Wert von b ist undefined
-var b;
-
-console.log("Der Wert von c ist " + c); // ReferenceError: c is not defined
-
-let x
-console.log("Der Wert von x ist " + x); // Der Wert von x ist undefined
-
-console.log("Der Wert von y ist " + y); // ReferenceError: y is not defined
-let y;
-
- -

undefined kann benutzt werden, um zu überprüfen ob eine Variable einen Wert hat. Im Folgenden Codebeispiel ist der Variable input kein Wert zugewiesen worden und das if-Statement wird somit true ausgeben.

- -
var input;
-if(input === undefined){
-  macheDas();
-} else {
-  macheDasAndere();
-}
-
- -

undefined verhält sich wie ein false, wenn es in einem boolschen Kontext verwendet wird. Zum Beispiel wird im folgendem Codebeispiel die Funktion myFunction ausgeführt, weil das myArray Element undefined ist:

- -
var myArray = [];
-if (!myArray[0]) myFunction();
-
- -

undefined wird zu NaN (Not a Number) konvertiert, wenn es in einem numerischen Kontext verwendet wird:

- -
var a;
-a + 2;  //NaN
- -

Wenn eine {{jsxref("null")}} Variable ausgewertet wird, verhält sie sich im numerischen Kontext wie 0 und in booleschem Kontext wie false:

- -
var n = null;
-console.log(n * 32);  // wird 0 in die Konsole eintragen
-
- -

Variablen Scope

- -

Wird eine Variable außerhalb eines Code-Blocks deklariert, wird sie eine globale Variable genannt, da sie jetzt in jedem Bereich verfügbar ist. Wenn eine Variable jedoch innerhalb eines Code-Blocks deklariert wird, so ist sie nur innerhalb dieses Blocks verfügbar und wird aus diesem Grund lokale Variable genannt.

- -

JavaScript hatte vor ECMAScript 2015 keinen Block-Anweisungs Scope; daher wurde eine deklarierte Variable in einem Block immer zu der Funktion (oder dem globalen Scope) gezählt, in dem sich der Block befand. Zum Beispiel wird der folgende Quelltext 5 ausgeben, weil der Scope von x die Funktion ist bzw. der globale Kontext, in dem x deklariert wurde, und nicht der Block, in diesem Fall die if Anweisung, selbst.

- -
if (true) {
-  var x = 5;
-}
-console.log(x);  // 5
-
- -

Das Verhalten ändert sich, wenn man die in ECMAScript 2015 eingeführte let Deklaration benutzt.

- -
if (true) {
-  let y = 5;
-}
-console.log(y);  // ReferenceError: y is not defined
-
- -

Variablen hochziehen (hoisting)

- -

Eine andere Besonderheit mit Variablen in JavaScript ist, dass man eine Variable referenzieren kann, bevor sie deklariert wurde, ohne das es zu einem Fehler kommt. Diese Konzept ist bekannt als hoisting (hochziehen); Variablen in JavaScript sind hochgezogen und quasi zum Anfang der Funktion oder des Statements gehoben worden. Immer wenn Variablen hochgezogen werden, werden sie den Wert undefined zurückgeben. So wird immer undefined zurückgegeben, wenn man die Variablen benutzt, bevor sie deklariert und initialisiert wurden.

- -
/**
- * Beispiel 1
- */
-console.log(x === undefined); // true
-var x = 3;
-
-/**
- * Beispiel 2
- * wird den Wert undefined zurückgeben
- */
-var myvar = "my value";
-
-(function() {
-  console.log(myvar); // undefined
-  var myvar = "local value";
-})();
-
- -

Das obere Beispiel wird genauso interpretiert, wie das folgende Beispiel:

- -
/**
- * Beispiel 1
- */
-var x;
-console.log(x === undefined); // true
-x = 3;
-
-/**
- * Beispiel 2
- */
-var myvar = "my value";
-
-(function() {
-  var myvar;
-  console.log(myvar); // undefined
-  myvar = "local value";
-})();
-
- -

Wegen des Hochziehens sollten alle var Anweisungen so weit am Anfang der Funktion wie nur möglich platziert werden. Dieses Vorgehen verbessert die Qualität des Quelltextes.

- -

In ECMAScript 2015 wird let (bzw. const) nicht an den Anfang eines Blocks hochgezogen. Das Referenzieren der Variable in dem Block, bevor diese deklariert wurde, führt zu einem {{jsxref("ReferenceError")}}. Die Variable ist in einer "temporären toten Zone", die vom Start des Blocks bis zur Deklaration der Variablen besteht.

- -
console.log(x); // ReferenceError
-let x = 3;
- -

Funktionen hochziehen (hoisting)

- -

Bei Funktionen (nur Funktionsdeklarationen) werden die Deklarationen ebenfalls nach oben gezogen. Bei Funktionsausdrücken gilt das jedoch nicht.

- -
/* Funktionsdeklaration */
-
-foo(); // "bar"
-
-function foo() {
-   console.log("bar");
-}
-
-
-/* Funktionsausdruck */
-
-baz(); // TypeError: baz ist keine Funktion
-
-var baz = function() {
-   console.log("bar2");
-};
-
- -

Globale Variablen

- -

Globale Variablen sind faktisch Eigenschaften des globalen Objekts. In Webseiten ist das globale Objekt das {{domxref("window")}} Objekt, so dass globale Variablen gesetzt und erreicht werden können, indem die Syntax window.variable eingesetzt wird.

- -

Folglich kann man globale Variablen, die in einem window oder frame deklariert wurden, aus einem anderen window oder Frame erreichen, indem der window oder framename angegeben wird. Zum Beispiel kann eine Variable phoneNumber, die in einem Dokument deklariert wurde, von einem iframe mit parent.phoneNumber erreicht werden.

- -

Konstanten

- -

Man kann eine nur lesende, benannte Konstante mit dem Schlüsselwort {{jsxref("Statements/const", "const")}} erstellen. Die Syntax für einen Konstantenbezeichner ist dieselbe, wie für Variablenbezeichner: Er muss mit einem Buchstaben, Unterstrich oder Dollarzeichen beginnen und kann alphabetische Zeichen, numerische Zeichen und Unterstriche enthalten.

- -
const PI = 3.14;
-
- -

Der Wert einer Konstanten kann nicht zur Laufzeit durch Zuweisungen oder Neudeklarationen geändert werden. Konstanten müssen deswegen immer initialisiert werden.

- -

Die Sichtbarkeitsregeln (Scope) bei Konstanten sind die gleichen, wie für let Blockscope Variablen. Wenn das Schüsselwort const weggelassen wird, wird vorausgesetzt, dass der Bezeichner eine Variable repräsentiert.

- -

Man kann keine Konstante mit dem gleichen Namen einer Funktion oder Variablen im gleiche Gültigkeitsbereich deklarieren. Zum Beispiel:

- -
// DAS WIRD ZU EINEM ERROR FÜHREN
-function f() {};
-const f = 5;
-
-// DAS WIRD EBENFALLS ZU EINEM ERROR FÜHREN
-function f() {
-  const g = 5;
-  var g;
-
-  //statements
-}
-
- -

Immer, wenn Objektattribute nicht geschützt sind, werden die folgenden Anweisungen ohne Probleme ausgeführt.

- -
const MY_OBJECT = {"key": "value"};
-MY_OBJECT.key = "otherValue";
- -

Jedoch ist der Inhalt eines Arrays nicht geschützt, sodass folgendes Statement ohne Probleme ausgeführt wird.

- -
const MY_ARRAY = ['HTML','CSS'];
-MY_ARRAY.push('JAVASCRIPT');
-console.log(MY_ARRAY); // logs ['HTML','CSS','JAVASCRIPT']
-
- -

Datenstrukturen und -typen

- -

Datentypen

- -

Der neuste ECMAScript Standard definiert sieben Datentypen:

- - - -

Obwohl die Anzahl der Datentypen relativ klein ist, eröffnen sie die Möglichkeit nützliche Funktionen für Applikationen zu erstellen. {{jsxref("Object", "Objects")}} und {{jsxref("Function", "functions")}} sind die anderen fundamentalen Elemente der Sprache. Man kann sich Objekte als benannte Container für Werte und Funktionen, die die Applikation ausführen kann, vorstellen.

- -

Datentypkonvertierungen

- -

JavaScript ist eine dynamisch typisierte Sprache. Das bedeutet, dass man den Datentypen einer Variable bei der Deklaration nicht mit angibt. Der Datentyp wird während der Ausführung automatisch konvertiert, wenn es notwendig ist. So kann eine Variable folgendermaßen definiert werden:

- -
var answer = 42;
-
- -

Und Später kann der gleichen Variablen eine Zeichenkette zugewiesen werden:

- -
answer = "Thanks for all the fish...";
-
- -

Weil JavaScript dynamisch typisiert ist, erzeugt diese Zuweisung keinen Fehler im Programm.

- -

In Ausdrücken, in denen Zahlen und Zeichenketten mit dem + Operator gebraucht werden, konvertiert JavaScript die Zahlen in Zeichenketten. Siehe dazu das folgende Beispiel:

- -
x = "The answer is " + 42 // "The answer is 42"
-y = 42 + " is the answer" // "42 is the answer"
-
- -

In Ausdrücken mit anderen Operatoren, konvertiert JavaScript zahlen nicht in Zeichenketten. Zum Beispiel:

- -
"37" - 7 // 30
-"37" + 7 // "377"
-
- -

Konvertieren von Zeichenketten zu Zahlen

- -

In Fällen, in denen eine Zahl durch einen String repräsentiert wird, gibt es folgende Methoden, um die Zeichenkette in eine Zahl umzuwandeln.

- - - -

parseInt gibt nur ganze Zahlen zurück, weshalb der Einsatz für Dezimalzahlen nicht geeignet ist. Zu einem guten Programmierstil gehört es, dass man immer die Basis bei parseInt mit angibt. Der radix Parameter der Methode gibt an, aus welchem Zahlensystem die Zahl stammt.

- -

Eine alternative Methode, um einen String in eine Zahl zu konvertieren ist der + (unär Plus) Operator:

- -
"1.1" + "1.1" // "1.11.1"
-(+"1.1") + (+"1.1") // 2.2
-// Hinweis: die hinzugefügten Klammern sind nur für die Lesbarkeit.
- -

Literale

- -

Man benutzt Literale, um in JavaScript Werte zu repräsentieren. Es sind feste Werte, keine Variablen, die man in einem Skript einsetzt. Dieses Kapitel beschreibt die folgeden Literaltypen:

- - - -

Array Literal

- -

Ein Array Literal ist eine Liste von null oder mehr Ausdrücken. Jeder Ausdruck repräsentiert ein Element des Arrays. Diese Elemente sind von eckigen Klammern ([]) umschlossen. Wenn ein Array mit einem Array Literal erstellt wird, wird das Array mit allen definierten Elementen initialisiert und die länge des Arrays wird auf die Menge der Elemente gesetzt.

- -

Das folgende Beispiel erstellt das coffees Array mit drei Elementen und der Länge drei:

- -
var coffees = ["French Roast", "Colombian", "Kona"];
-
- -
-

Hinweis: Ein Array Literal ist eine Art von Objektinitialisierung. Sie dazu auch den Einsatz von Objektinitialisierern.

-
- -

Wenn ein Array durch ein Literal im Toplevel Skript erstellt wird, interpretiert JavaScript das Array immer dann, wenn ein Ausdruck dieses Literal enthält. Im Gegensatz dazu wird ein Literal in einer Funktion immer neu erstellt, wenn die Funktion aufgerufen wird.

- -

Array Literale sind ebenfalls Array Objekte. Für mehr Details siehe {{jsxref("Array")}} und Indexed collections.

- -

Extra Kommas in Array Literalen

- -

Man muss nicht alle Elemente in einem Array Literal spezifizieren. Wenn man zwei Kommas in einer Reihe verwendet, wird das Array mit einem undefined Element erstellt. Das folgende Beispiel erstellt das fish Array:

- -
var fish = ["Lion", , "Angel"];
-
- -

Dieses Array hat zwei Elemente mit Werten und ein leeres Element (fish[0] ist "Lion", fish[1] ist undefined und fish[2] ist "Angel").

- -

Wenn man ein trennendes Komma am Ende der Elementliste hinzufügt, wird es ignoriert. Im folgenden Beispiel ist die Länge des Arrays drei. Es gibt kein myList[3]. Alle weiteren Kommas in der Liste führen zu einem neuen Element.

- -
-

Hinweis: Trennende Kommas können in älteren Browserversionen zu Fehlern führen. Zudem ist es ein guter Stil diese Kommas zu entfernen.

-
- -
var myList = ['home', , 'school', ];
-
- -

Im folgenden Beispiel hat das Array vier Elemente und myList[0] und myList[2] sind nicht spezifiziert.

- -
var myList = [ , 'home', , 'school'];
-
- -

Im folgenden Beispiel hat das Array vier Elemente und myList[1] und myList[3] sind nicht spezifiziert. Nur das letzte Komma wird ignoriert.

- -
var myList = ['home', , 'school', , ];
-
- -

Das Verständnis für das Verhalten von extra Kommas ist wichtig, um JavaScript als Sprache zu verstehen. Immer, wenn man seinen eigenen Quelltext schreibt, sollten explizit fehlenden Elementen mit undefined deklariert werden, damit die Lesbarkeit und Wartbarkeit des Quelltextes besser ist.

- -

Boolean Literale

- -

Der Boolean Typ hat zwei Literale: true und false.

- -

Man sollte die primitiven Werte true und false jedoch nicht mit den Werten true und false des Boolean Objektes verwechseln. Das Boolean Objekt ist eine Hülle um den primitiven Boolean Datentypen. Siehe im Artikel {{jsxref("Boolean")}} für weitere Informationen.

- -

Numerische Literale

- -

Ganze Zahlen können als Dezimal- (Basis 10), Hexadezimal- (Basis 16), Oktal- (Basis 8) und Binärzahl (Basis 2) ausgedrückt werden.

- - - -

Im folgenden Beispiel sind einige Beispiele für Zahlenliterale:

- -
0, 117 und -345 (dezimal, Basis 10)
-015, 0001 und -0o77 (oktal, Basis 8)
-0x1123, 0x00111 und -0xF1A7 (hexadezimal, "hex", Base 16)
-0b11, 0b0011 und -0b11 (binär, Basis 2)
-
- -

Für weitere Informationen siehe numerische Literale in der Lexikalischen Grammatik Referenz.

- -

Gleitkomma Literale

- -

Ein Gleitkomma Literal kann die folgenden Abschnitte beinhalten:

- - - -

Der Exponent besteht aus einem "e" oder "E" gefolgt von einer ganzen Zahl, die mit einem Vorzeichen ("+" oder "-") versehen sein kann. Eine Gleitkommazahl muss mindestens aus einer Ziffer und entweder einem Dezimalpunkt oder einem "e" (oder "E") bestehen.

- -

Kurz und knapp sieht die Syntax folgendermaßen aus:

- -
[(+|-)][ziffern][.ziffern][(E|e)[(+|-)]ziffern]
-
- -

Zum Beispiel:

- -
3.1415926
--.123456789
--3.1E+12
-.1e-23
-
- -

Objekt Literale

- -

Ein Objekt Literal ist eine Liste von null oder mehr Paaren von Eigenschaftsnamen und -werten, umschlossen von geschweiften Klammern ({}). Man sollte kein Objektliteral am Anfang eines Statements benutzen. Das wird zu einem Fehler führen oder nicht wie erwartet funktionieren, weil das {-Zeichen als Anfang eines Blocks interpretiert wird.

- -

Es folgt ein Beispiel für ein Objekt Literal. Das erste Element des car Objektes definiert eine Eigenschaft myCar und beschreibt diese mit einem neuen String "Saturn". Am zweiten Element, der getCar Eigenschaft, wird der Rückgabewert der aufgerufenen Funktion carTypes("Honda") zugewiesen. Das dritte Element, die special Eigenschaft, benutzt eine existierende Variable sales.

- -
var sales = "Toyota";
-
-function carTypes(name) {
-  if (name === "Honda") {
-    return name;
-  } else {
-    return "Sorry, we don't sell " + name + ".";
-  }
-}
-
-var car = {
-  myCar: "Saturn",
-  getCar: carTypes("Honda"),
-  special: sales
-};
-
-console.log(car.myCar);   // Saturn
-console.log(car.getCar);  // Honda
-console.log(car.special); // Toyota
-
- -

Für die Namen der Eigenschaften kann auch ein String oder ein Zahlen Literal verwendet werden. Für den Wert kann auch ein verschachteltes Objekt Literal genutzt werden. Das folgende Beispiel nutzt diese Optionen.

- -
var car = { manyCars: {a: 'Saab', b: 'Jeep'}, 7: 'Mazda' };
-
-console.log(car.manyCars.b); // Jeep
-console.log(car[7]); // Mazda
-
- -

Die Namen von Objekteigenschaften können ein String sein, was auch den leeren String beinhaltet. Wenn die Eigenschaftsnamen keine gültigen JavaScript {{Glossary("Identifier","Bezeichner")}} sind, müssen sie in Anführungszeichen geschrieben werden. Eigenschaftsnamen die keine gültigen Bezeichner sind, können nicht mit der Punktschreibweise (.) erreicht werden. Wohl aber mit der Array ähnlichen Notation ("[]").

- -
var unusualPropertyNames = {
-  "": "An empty string",
-  "!": "Bang!"
-}
-console.log(unusualPropertyNames."");   // SyntaxError: Unexpected string
-console.log(unusualPropertyNames[""]);  // An empty string
-console.log(unusualPropertyNames.!);    // SyntaxError: Unexpected token !
-console.log(unusualPropertyNames["!"]); // Bang!
- -

Erweiterte Objekt Literale

- -

In ES2015 wurde das Objekt Literal dahingehend erweitert, dass der Prototyp bei der Erstellung gesetzt wird. Desweiteren sind neue Funktionalitäten hinzugekommen, die eine Kurzschreibweise für foo: foo Zuweisungen, die Definitionen für Methoden, das Aufrufen von super Methoden und die Berechnung der Eigenschaftsnamen mit Ausdrücken ermöglichen. Alle diese Funktionen bringen zum Einen Klassendefinition und Objekt Literale näher zusammen und sind somit objektbasiertes Design und zum Anderen häufig vorteilhafter und bequemer.

- -
var obj = {
-    // __proto__
-    __proto__: theProtoObj,
-    // Shorthand for ‘handler: handler’
-    handler,
-    // Methods
-    toString() {
-     // Super calls
-     return "d " + super.toString();
-    },
-    // Computed (dynamic) property names
-    [ 'prop_' + (() => 42)() ]: 42
-};
- -

Bitte beachten:

- -
var foo = {a: "alpha", 2: "two"};
-console.log(foo.a);    // alpha
-console.log(foo[2]);   // two
-//console.log(foo.2);  // Error: missing ) after argument list
-//console.log(foo[a]); // Error: a is not defined
-console.log(foo["a"]); // alpha
-console.log(foo["2"]); // two
-
- -

RegExp Literale

- -

Ein RegExp Literal (welcher im Detail später erklärt wird) ist ein Pattern (Muster) umschlossen von Slashes (/). Das Folgende ist ein Beispiel für ein RegExp Literal:

- -
var re = /ab+c/;
- -

String Literale

- -

Ein String Literal besteht aus null oder mehr Zeichen, die von doppelten (") oder einfachen (') Anführungszeichen umschlossen sind. Ein String muss immer von gleichen Anführungszeichen umschlossen sein. Entweder von einfachen oder von doppelten Anführungszeichen. Im folgenden Beispiel sind ein paar String Literale gezeigt:

- -
"foo"
-'bar'
-"1234"
-"eine Zeile \n weitere Zeile"
-"John's cat"
-
- -

Man kann alle Methoden des String Objektes auf einem String Literal aufrufen, denn JavaScript konvertiert das Literal automatisch in ein temporäres String Objekt, führt die Methode aus und verwirft danach das temporäre Objekt. Man kann auch die String.length Eigenschaft mit einem String Literal benutzen:

- -
console.log("John's cat".length)
-// Wird die Anzahl der Zeichen (auch Leerzeichen) ausgeben.
-// In diesem Fall 10.
-
- -

In ES2015, wurden zudem Template Literale eingeführt. Template Literale sind von Backticks (` `) (Gravis) umschlossen. Template Strings bieten syntaktischen Zucker für das Erstellen von Strings an. Sie sind vergleichbar mit den String Interpolations Funktionen in Perl, Python und anderen Sprachen. Optional können Marken eingefügt werden, um einen String benutzerdefiniert zu erstellen. Sie vermeiden Injection-Attacken und ermöglichen es Datenstrukturen in Strings unterzubringen.

- -
// Standardliteral für die String erstellung
-`In JavaScript '\n' is a line-feed.`
-
-// Mehrzellige Strings
-`In JavaScript ist das
- nicht erlaubt.`
-
-// String Interpolation
-var name = "Bob", time = "today";
-`Hello ${name}, how are you ${time}?`
-
-// Erstellung einer HTTP Anfrage.
-POST`http://foo.org/bar?a=${a}&b=${b}
-     Content-Type: application/json
-     X-Credentials: ${credentials}
-     { "foo": ${foo},
-       "bar": ${bar}}`(myOnReadyStateChangeHandler);
- -

Man sollte String Literale benutzen, sofern man nicht explizit ein Objekt benötigt. Für weitere Informationen siehe im {{jsxref("String")}} Artikel nach.

- -

Einsatz von Sonderzeichen in Strings

- -

Neben den normalen Zeichen ist es auch möglich Sonderzeichen in einem String zu verwenden. Ein Beispiel ist im folgenden zu sehen:

- -
"eine Zeile \n nächste Zeile"
-
- -

Die folgende Tabelle Zeigt die Sonderzeichen, die in JavaScript Strings verwendet werden können:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table: JavaScript Sonderzeichen
ZeichenBedeutung
\0Null Byte
\bBackspace
\fForm feed
\nNew line
\rCarriage return
\tTab
\vVertical tab
\'Einfache Anführungszeichen
\"Doppelte Anführungszeichen
\\Backslash Zeichen
\XXXDas Zeichen, das im Latin-1 Encoding mit drei Oktalzahlen (XXX) Spezifiziert wird (0 bis 377). Zum Beispiel ist \251 die Oktalsequenz für das Copyrightsymbol.
\xXXZeichen, die im Latin-1 Encoding mit zwei Hexadezimalzahlen (XX) spezifiziert werden (00 bis FF). Zum Beispiel ist \xA9 die Hexadezimalsequenz für das Copyrightsymbol.
\uXXXXDie Unicode Zeichen, die mit vier Hexadezimalziffern XXXX beschreiben werden. Zum Beispiel ist \u00A9 die Hexadezimalsequenz für das Copyrightsymbol. Siehe Unicode escape Sequenzen.
\u{XXXXX}Unicode code point escapes. Zum Beispiel ist \u{2F804} das gleiche wie das einfache Unicodezeichen \uD87E\uDC04.
- -

Escaping Zeichen

- -

Für nicht in der Tabelle gezeigte Zeichen wird ein voranstehendes Backslash ignoriert. Der Einsatz von Backslashs ist Veraltet und sollte vermieden werden.

- -

Man kann Anführungszeichen in einen String hinzufügen, indem ein Führendes Backslash eingesetzt wird. Das wird auch escaping der Anführungszeichen genannt. Ein Beispiel:

- -
var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service.";
-console.log(quote);
-
- -

Das Ergebnis ist:

- -
He read "The Cremation of Sam McGee" by R.W. Service.
-
- -

Um ein Backslash in einem String zu verwenden, muss dieses mit einem Backslash escaped werden. Zum Beispiel muss der Pfad c:\temp wie folgt geschrieben werden:

- -
var home = "c:\\temp";
-
- -

Man kann zudem Zeilenumbrüche mit einem vorangegangenen Backslash escapen. Das Backslash und der Zeilenumbruch werden aus dem String entfernt.

- -
var str = "this string \
-is broken \
-across multiple\
-lines."
-console.log(str);   // this string is broken across multiple lines.
-
- -

JavaScript kennt keine "heredoc" Syntax. Um eine solche zu simulieren muss am Ende jeder Zeile mit einem Zeilenumbruch (\n) ein Backslash stehen:

- -
var poem =
-"Roses are red,\n\
-Violets are blue.\n\
-Sugar is sweet,\n\
-and so is foo."
-
- -

ECMAScript 2015 führte einen neuen Literaltyp, das Template Literal, ein. Dieses führte, für viele neue Funktionen, Strings mit mehrere Zeilen ein!

- -
var poem =
-`Roses are red,
-Violets are blue.
-Sugar is sweet,
-and so is foo.`
-
- -

Mehr Informationen

- -

Dieses Kapitel beschränkt sich auf die Basissyntax für Deklarationen und Typen. Um mehr über die Sprachkonstrukte von JavaScript zu lernen siehe in die folgenden Kapitel dieses Guides:

- - - -

Im nächsten Kapitel wird ein Blick auf Kontrollflüsse und Fehlerbehandlungen geworfen.

- -

{{PreviousNext("Web/JavaScript/Guide/Einführung", "Web/JavaScript/Guide/Kontrollfluss_und_Fehlerbehandlung")}}

diff --git a/files/de/web/javascript/guide/introduction/index.html b/files/de/web/javascript/guide/introduction/index.html new file mode 100644 index 0000000000..b38cb1b700 --- /dev/null +++ b/files/de/web/javascript/guide/introduction/index.html @@ -0,0 +1,140 @@ +--- +title: Einführung +slug: Web/JavaScript/Guide/Einführung +tags: + - Beginner + - Guide + - Introduction + - JavaScript + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Introduction +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammatik_und_Typen")}}
+ +

Dieses Kapitel stellt JavaScript vor und behandelt einige grundlegende Konzepte.

+ +

Was solltest du bereits wissen

+ +

Für diese Einführung solltest du die folgenden Grundkenntnisse besitzen:

+ + + +

Wo findest du Informationen zu JavaScript

+ +

Die Dokumentation zu JavaScript im MDN umfasst Folgendes:

+ + + +

Falls du dich das erste Mal mit JavaScript befasst, beginne einfach mit den Tutorials von Learning the Web [de] und dem JavaScript Guide [de]. Sobald du mit den ersten Grundlagen vertraut bist, kannst du die JavaScript Referenz [de] nutzen, um noch mehr über die einzelnen Methoden, Funktionen und Objekte von JavaScript zu erfahren.

+ +

Was ist JavaScript?

+ +

JavaScript ist eine plattformübergreifende, objektorientierte Skriptsprache. Es ist eine kompakte und ressourcenschonende Sprache. Innerhalb einer Host-Umgebung kann JavaScript mit den Objekten seiner Umgebung verknüpft werden, um diese programmatisch zu steuern.

+ +

JavaScript beinhaltet eine Standardbibliothek von Objekten wie Array, Date, und Math, sowie einen Kern an Sprachelementen wie Operatoren, Kontrollstrukturen und Anweisungen. Der JavaScript-Kern kann für eine Vielzahl von Anwendungsfällen erweitert werden, indem man ihn durch zusätzliche Objekte ergänzt. Beispiele:

+ + + +

JavaScript und Java

+ +

JavaScript und Java gleichen einander in manchen Aspekten, sind in anderen aber grundlegend verschieden. Die Sprache JavaScript ähnelt Java, verfügt jedoch nicht über Javas statische Typisierung und seine strenge Typprüfung. JavaScript folgt weitgehend der Ausdruckssyntax, den Namenskonventionen und den elementaren Kontrollstrukturen von Java, was der Grund für die Umbenennung von LiveScript in JavaScript gewesen ist.

+ +

Im Gegensatz zu Javas durch Deklarationen aufgebautes System, von zur Compile-Zeit verfügbaren Klassen, unterstützt JavaScript ein Laufzeitsystem, das auf einer kleinen Zahl an Datentypen basiert, die numerische und Boolesche Werte sowie Zeichenketten repräsentieren. JavaScript besitzt ein prototypen-basiertes Objektmodell anstatt des verbreiteteren klassenbasierten. Das prototypen-basierte Modell liefert dynamische Vererbung; das bedeutet, was vererbt wird, kann zwischen einzelnen Objekten variieren. JavaScript unterstützt zudem Funktionen ohne spezielle deklarative Anforderungen. Funktionen können Objekt Eigenschaften sein, ausgeführt als schwach typisierte Methoden.

+ +

JavaScript ist im Vergleich zu Java eine syntaktisch sehr freie Sprache. Sie müssen nicht alle Variablen, Klassen und Methoden deklarieren. Sie müssen sich nicht damit befassen, ob Methoden öffentlich, privat oder geschützt sind und Sie müssen keine Interfaces implementieren. Variablen, Parameter und Rückgabewerte von Funktionen sind nicht explizit typisiert.

+ +

Java ist eine auf schnelle Ausführung und Typsicherheit ausgelegte, klassenbasierte Programmiersprache. Typsicherheit bedeutet, dass Sie zum Beispiel keine Ganzzal in Java in eine Objektreferenz wandeln oder auf geschützten Speicher zugreifen können, indem Sie den Bytecode von Java manipulieren. Javas klassenbasiertes Modell bedeutet, dass Programme ausschließlich aus Klassen und ihren Methoden bestehen. Javas Klassenvererbung und strenge Typisierung erfordern im Allgemeinen eng gekoppelte Objekthierarchien. Wegen dieser Anforderungen ist das Programmieren in Java komplexer als in JavaScript.

+ +

Im Gegensatz dazu steht JavaScript in der Tradition einer Reihe kleiner, dynamisch typisierter Sprachen wie HyperTalk und dBase. Diese Skriptsprachen stellen, dank ihrer einfacheren Syntax, spezialisierter eingebauter Funktionalität und minimalen Anforderungen, für die Objektgenerierung Programmierwerkzeuge für einen deutlich breiteren Adressatenkreis zu Verfügung.

+ + + + + + + + + + + + + + + + + + + + + + + +
JavaScript im Vergleich zu Java
JavaScriptJava
Objektorientiert. Keine Unterscheidung zwischen Typen von Objekten. Vererbung mittels des Prototypen-Mechanismus, jedes beliebige Objekt kann dynamisch um Eigenschaften und Methoden erweitert werden.Klassenbasiert. Objekte werden in Klassen und Instanzen unterteilt, Vererbung erfolgt vollständig über die Klassenhierarchie. Klassen und Instanzen können keine Eigenschaften und Methoden dynamisch hinzugefügt werden.
Datentypen von Variablen werden nicht deklariert (dynamische Typisierung)Datentypen von Variablen müssen deklariert werden (statische Typisierung)
Kein automatischer Schreibzugriff auf die Festplatte.Kein automatischer Schreibzugriff auf die Festplatte.
+ +

Weitere Informationen zu den Unterschieden zwischen JavaScript und Java finden Sie im Kapitel Einzelheiten des Objektmodells.

+ +

JavaScript und die ECMAScript-Spezifikation

+ +

JavaScript wird durch Ecma International standardisiert — den europäischen Verband zur Standardisierung von Informations- und Telekommunikationssystemen (ECMA war vormals ein Akronym für 'European Computer Manufacturers Association'), um eine standardisierte, internationale Programmiersprache auf der Basis von JavaScript verfügbar zu machen. Diese standardisierte Version von JavaScript, genannt ECMAScript, verhält sich in allen standardkonformen Applikationen identisch. Unternehmen können die offene Sprachdefinition verwenden, um ihre eigene Implementierung von JavaScript zu entwickeln. Der ECMAScript-Standard ist in der Spezifikation ECMA-262 dokumentiert. Unter Neu in JavaScript erfahren Sie mehr über die unterschiedlichen Versionen von JavaScript und den ECMAScript-Spezifikationen.

+ +

ECMA-262 ist auch von der ISO (International Organization for Standardization) als ISO-16262 verabschiedet. Sie finden die Spezifikation auch auf der Website von Ecma International. Die Spezifikation von ECMAScript beschreibt nicht das Document Object Model (DOM), welches durch das World Wide Web Consortium (W3C) und der WHATWG (Web Hypertext Application Technology Working Group) standardisiert wird. Das DOM definiert die Art und Weise, in der HTML-Dokumentenobjekte für Ihr Skript sichtbar sind. Um ein besseres Verständnis der verschiedenen bei der Programmierung in JavaScript eingesetzten Technologien zu entwickeln, lesen Sie den Artikel JavaScript Technologieübersicht.

+ +

JavaScript-Dokumentation vs. ECMAScript-Spezifikation

+ +

Die Spezifikation von ECMAScript besteht aus Anforderungen an eine Implementierung von ECMAScript; sie ist zweckdienlich, falls Sie standardkonforme Spracheigenschaften in Ihrer ECMAScript-Implementierung oder ihrer Laufzeitumgebung (wie SpiderMonkey in Firefox oder v8 in Chrome) realisieren wollen.

+ +

Das ECMAScript-Dokument soll nicht den Skriptprogrammierer unterstützen; nutzen Sie für Informationen zum Erstellen von Skripten die JavaScript-Dokumentation.

+ +

Die ECMAScript-Spezifikation verwendet Terminologie und Syntax, mit der JavaScript-Programmierer möglicherweise nicht vertraut sind. Obwohl sich die Beschreibung der Sprache in ECMAScript unterscheiden kann, bleibt die Sprache selbst die gleiche. JavaScript unterstützt jede Funktionalität, die in der ECMAScript-Spezifikation genannt wird.

+ +

Die JavaScript-Dokumentation beschreibt Aspekte der Sprache in für JavaScript-Programmierer passender Form.

+ +

Erste Schritte mit JavaScript

+ +

Die ersten Schritte mit JavaScript sind einfach: alles was Sie brauchen, ist einen aktuellen Browser. Diese Einführung nimmt auf einige Spracheigenschaften von JavaScript Bezug, die zur Zeit nur in den jüngsten Versionen von Firefox verfügbar sind, somit wird die Nutzung der aktuellsten Firefox-Version empfohlen.

+ +

Es gibt zwei Werkzeuge in Firefox, die zum Experimentieren mit JavaScript nützliche sind: die Web-Konsole and die JavaScript-Umgebung.

+ +

Die Web-Konsole

+ +

Die Web-Konsole zeigt Ihnen Informationen zur aktuell geladenen Webseite an und beinhaltet zudem eine Kommandozeile, die Sie nutzen können, um JavaScript-Ausdrücke im Kontext der aktuellen Seite auszuführen.

+ +

Um die Web-Konsole zu öffnen (Ctrl+Shift+K), wählen Sie "Web-Konsole" im Menü "Entwicklerwerkzeuge", das Sie im Menü von Firefox finden. Die Konsole wird am unteren Rand des Browserfensters angezeigt. Entlang des unteren Randes der Konsole befindet sich die Kommandozeile, in der Sie JavaScript eingeben können; die zugehörige Ausgabe erscheint im darüberliegenden Fensterbereich:

+ +

+ +

JavaScript-Umgebung (Scratchpad)

+ +

Die Web-Konsole eignet sich hervorragend zur Ausführung einzelner Zeilen JavaScript, möchten Sie jedoch mehrere Zeilen ausführen können, ist das nicht besonders komfortabel und Ihren Beispielcode speichern können Sie mit der Web-Konsole auch nicht. Daher ist für komplexere Beispiele die JavaScript-Umgebung die bessere Wahl.

+ +

Um die JavaScript-Umgebung zu öffnen (Shift+F4), wählen Sie "JavaScript-Umgebung" aus dem Menü "Entwicklerwerkzeuge", das Sie im Firefox-Menü finden. Die JavaScript-Umgebung öffnet sich in einem eigenen Fenster als Editor, mit dem Sie JavaScript schreiben und im Browser ausführen können. Sie können auch Skripte auf der Festplatte speichern bzw. laden.

+ +

+ +

Hello world

+ +

Beginnen Sie mit dem Programmieren in JavaScript, indem Sie die JavaScript-Umgebung öffnen und Ihr erstes "Hello World"-Programm in JavaScript schreiben:

+ +
function greetMe(yourName) {
+  alert("Hello " + yourName);
+}
+
+greetMe("World");
+
+ +

Markieren Sie den Quelltext und drücken Sie Ctrl+R, um zu schauen, ob alles funktioniert.

+ +

Auf den folgenden Seiten macht Sie diese Einführung mit Syntax und Spracheigenschaften von JavaScript vertraut, sodass Sie bald komplexere Anwendungen schreiben können.

+ +

{{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammatik_und_Typen")}}

diff --git a/files/de/web/javascript/guide/kontrollfluss_und_fehlerbehandlung/index.html b/files/de/web/javascript/guide/kontrollfluss_und_fehlerbehandlung/index.html deleted file mode 100644 index 97dbba8b3e..0000000000 --- a/files/de/web/javascript/guide/kontrollfluss_und_fehlerbehandlung/index.html +++ /dev/null @@ -1,430 +0,0 @@ ---- -title: Kontrollfluss und Fehlerbehandlung -slug: Web/JavaScript/Guide/Kontrollfluss_und_Fehlerbehandlung -tags: - - Beginner - - Guide - - JavaScript - - 'l10n:priority' -translation_of: Web/JavaScript/Guide/Control_flow_and_error_handling ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Grammatik_und_Typen", "Web/JavaScript/Guide/Schleifen_und_Iterationen")}}
- -

JavaScript unterstützt eine Menge von Anweisungen, speziell um Verlaufs-Anweisungen zu kontrollieren, welches eine großartige Methode ist um Interaktivität in deine Anwendung einzuarbeiten. Dieses Kapitel liefert dir ein Überblick über diese Anweisungen.

- -

Die JavaScript Referenzen beinhalten umfassende Details über die Anweisungen in diesem Kapitel. Das Semikolon (;) als Zeichen wird genutzt um Anweisungen im JavaScript Code einzuteilen.

- -

Jeder JavaScript Ausdruck ist auch eine Anweisung. Schau ebenfalls in Ausdrücke und Operatoren, um komplette Informationen über Ausdrücke zu erhalten.

- -

Block-Anweisungen

- -

Das einfachste Statement ist das Block-Statement, welches genutzt wird um Anweisungen zu gruppieren. Dieser Block wird von einem Paar geschweiften Klammer umschlossen:

- -
{
-  statement_1;
-  statement_2;
-  .
-  .
-  .
-  statement_n;
-}
-
- -

Beispiele

- -

Block-Statements werden meistens mit Kontrollfluss-Statements genutzt (z. B. if, for, while).

- -
while (x < 10) {
-  x++;
-}
-
- -

Hier ist, { x++; } das Block-Statement.

- -

Wichtig: JavaScript hat vor ECMAScript2015 keine Block-Scopes. Variablen, die in einem Block deklariert werden, gehören zu der Funktion oder dem Skript und das Beschreiben der Variablen führt dazu, dass diese über den Block hinaus verfügbar ist. In anderen Worten, Block-Statements definieren keinen Scope. Alleinstehende Blöcke in JavaScript können komplett andere Ergebnisse erzeugen als in C oder Java. Zum Beispiel:

- -
var x = 1;
-{
-  var x = 2;
-}
-console.log(x); // outputs 2
-
- -

Hier wird 2 ausgegeben, weil var x innerhalb des Blocks im gleichen Scope ist wie das var x vor dem Block. In C oder Java hätte der selbe Code 1 ausgegeben.

- -

Seit ECMAScript2015 sind let und const Variablendeklarationen, die an den Block gebunden sind. Siehe dazu auch die Referenzseiten {{jsxref("Statements/let", "let")}} und {{jsxref("Statements/const", "const")}} an.

- -

Bedingte Statements

- -

Ein bedingtes Statement ist eine Menge von Befehlen, die ausgeführt werden, wenn eine Bedingung wahr ist. JavaScript unterstützt zwei bedingte Statements: if...else und switch.

- -

if...else Anweisungen

- -

if wird eingesetzt um Statements auszuführen, wenn eine logische Bedingung wahr wird. Mit der optionalen else-Klausel werden Statements ausgeführt, wenn die Bedingung falsch ist. Ein if-Block sieht folgendermaßen aus:

- -
if (bedingung) {
-  statement_1;
-} else {
-  statement_2;
-}
- -

Hier kann die Bedingung ein Ausdruck sein, der zu true oder false ausgewertet wird. Siehe Boolean nach, um zu erfahren, was zu true und was zu false ausgewertet wird. Wenn bedingung zu true ausgewertet wird, wird statement_1 ausgeführt. Andernfalls wird statement_2 ausgeführt. statement_1 und statement_2 können beliebige Statements sein, auch weitere if-Statements.

- -

Man kann zudem Statements mit else if konstruieren, um mehrere Bedingungen sequentiell zu testen:

- -
if (bedingung_1) {
-  statement_1;
-} else if (bedingung_2) {
-  statement_2;
-} else if (bedingung_n) {
-  statement_n;
-} else {
-  statement_last;
-}
-
- -

Um mehrere Statements auszuführen, werden diese in Blockstatements gruppiert ({ ... }). Generell ist es guter Stil immer Block-Statements zu benutzen, besonders bei verschachtelten if-Statements.

- -
if (bedingung) {
-  statement_1_runs_if_condition_is_true;
-  statement_2_runs_if_condition_is_true;
-} else {
-  statement_3_runs_if_condition_is_false;
-  statement_4_runs_if_condition_is_false;
-}
-
- -

Es ist ratsam, keine einfachen Zuweisungen in Bedingungen zu verwenden, da die Zuordnung mit der Prüfung auf Gleichheit verwechselt werden kann, wenn man über den Code schaut. Verwenden Sie zum Beispiel den folgenden Code nicht:

- -
if (x = y) {
-  /* statements here */
-}
-
- -

Wenn eine Zuweisung in einer Bedingung benötigt wird, ist es verbreitet diese in weitere runde Klammeren zu schreiben. Zum Beispiel:

- -
if ((x = y)) {
-  /* statements here */
-}
-
- -

Falsy Werte

- -

Die folgenden Werte werden zu false ausgewertet (auch bekannt als {{Glossary("Falsy")}} Werte):

- - - -

Alle anderen Werte, auch alle Objekte, werden zu true ausgewertet, wenn sie als Bedingung eingesetzt werden.

- -

Es ist jedoch etwas verwirrend mit den primitiven boolean Werten true und false und den Werten des {{jsxref("Boolean")}}-Objektes, wie folgendes Beispiel zeigt:

- -
var b = new Boolean(false);
-if (b)          // Die Bedingung wird zu true ausgewertet.
-if (b == true)  // Die Bedingung wird zu false ausgewertet.
- -

Beispiel

- -

Im folgenden Beispiel gibt die Funktion checkData true zurück, wenn die Anzahl der Zeichen in einem Text Objekt drei ist. Andernfalls wird ein Alert angezeigt, und false zurückgegeben.

- -
function checkData() {
-  if (document.form1.threeChar.value.length == 3) {
-    return true;
-  } else {
-    alert("Enter exactly three characters. " +
-    document.form1.threeChar.value + " is not valid.");
-    return false;
-  }
-}
-
- -

switch Statement

- -

Ein switch Statement erlaubt es einen Ausdruck auszuwerten und das Resultat zu einem passenden Fall-Label (case-Label ) zuzuordnen. Wenn ein passendes Fall-Label gefunden wird, werden die zugehörigen Statements ausgeführt. Ein switch Statement sieht wie folgt aus:

- -
switch (ausdruck) {
-  case label_1:
-    statements_1
-    [break;]
-  case label_2:
-    statements_2
-    [break;]
-    ...
-  default:
-    statements_def
-    [break;]
-}
-
- -

Das Programm sucht als erstes nach eine case-Klausel mit einem Label, welches mit dem Wert des Ausgewerteten Ausdrucks übereinstimmt und gibt die Kontrolle zu dieser Klausel, was bedeutet, dass die zugehörigen Statements ausgeführt werden. Wenn kein passendes Label gefunden wird, sucht das Programm nach der optionalen default-Klausel und gibt die Kontrolle an diese, was bedeutet, dass die zugehörigen Statements ausgeführt werden. Wenn keine default-Klausel vorhanden ist, wird das switch beendet und das nächste Statement wird ausgeführt. Laut Konventionen ist die default-Klausel die letzte Klausel, das muss aber nicht immer so sein.

- -

Das optionale break Statement, welches in jeder case-Klausel eingesetzt ist, sorgt daführ, dass nach der Klausel das switch Statement beendet wird und das Programm mit dem nachfolgenden Statement weiter macht. Wenn break weggelassen wird, wird das Programm mit dem nächsten Statement im switch weitermachen, was dazu führt, dass alle nachlogenden case-Klauseln und die optionale default-Klausel mit ausgeführt werden.

- -

Beispiel

- -

Im folgenden Beispiel wird der case "Bananas" ausgeführt, wenn fruittype zu "Bananas" ausgewertet wird. Die break Statements bewirken, dass das switch beendet wird und das nach switch stehende Statement ausgeführt wird. Wird break im case "Bananas" weggelassen, so wird der case "Cherries" mit ausgeführt.

- -
switch (fruittype) {
-  case 'Oranges':
-    console.log('Oranges are $0.59 a pound.');
-    break;
-  case 'Apples':
-    console.log('Apples are $0.32 a pound.');
-    break;
-  case 'Bananas':
-    console.log('Bananas are $0.48 a pound.');
-    break;
-  case 'Cherries':
-    console.log('Cherries are $3.00 a pound.');
-    break;
-  case 'Mangoes':
-    console.log('Mangoes are $0.56 a pound.');
-    break;
-  case 'Papayas':
-    console.log('Mangoes and papayas are $2.79 a pound.');
-    break;
-  default:
-   console.log('Sorry, we are out of ' + fruittype + '.');
-}
-console.log("Is there anything else you'd like?");
- -

Statements zur Fehler- bzw. Ausnahmebehandlung

- -

Man kann mit dem throw Statement Fehler werfen (erzeugen) und diese mit dem Einsatz des try...catch Statements auffangen und verarbeiten.

- - - -

Ausnahmetypen

- -

Jedes Objekt in JavaScript kann als Fehler bzw. Ausnahme geworfen werden. Nicht alle Fehlerobjekte müssen auf die gleiche Art und Weise erstellt worden sein. Trotz des häufig Einsatzes von Zahlen oder Strings als Ausnahmen ist es deutlich effektiver die speziell für Ausnahmen erstellten Typen zu benutzen:

- - - -

throw Statement

- -

Das throw Statement wird benutzt, um eine Exception (Ausnahme / Fehler) zu werfen. Wenn eine Exception geworfen wird, so wird ein Ausdruck spezifiziert, welcher den Wert, welcher geworfen wird, spezifiziert:

- -
throw ausdruck;
-
- -

Man kann jeden Ausdruck werfen, nicht nur Ausdrücke eines bestimmten Typs. Der folgende Code wirft mehrere Ausnahmen verschiedenen Typs:

- -
throw "Error2";   // String type
-throw 42;         // Number type
-throw true;       // Boolean type
-throw {toString: function() { return "I'm an object!"; } };
-
- -
Notiz: Man kann ein Objekt beim Werfen einer Exception spezifizieren. Im catch Block können die Eigenschaften des Objektes referenziert werden.
- -
// Erstellt ein Objekt vom Typ UserException
-function UserException (message){
-  this.message=message;
-  this.name="UserException";
-}
-
-// Macht die Konvertierung der Exception in einen schönen String, wenn die Exception
-// als String genutzt werden soll.
-// (z. B. in der Fehlerconsole)
-UserException.prototype.toString = function () {
-  return this.name + ': "' + this.message + '"';
-}
-
-// Erstellt eine Instanz der UserException und wirft diese
-throw new UserException("Value too high");
- -

try...catch Statement

- -

Das try...catch Statement markiert einen Block von Statements, welcher versucht wird auszuführen, und einen oder mehrere Blöcke welche auf geworfene Exceptions abfangen. Wenn eine Exception geworfen wird, fängt das try...catch Statements diese ab.

- -

Das try...catch Statement besteht aus einem try Block, welcher ein oder mehrere Statements enthält, und null oder mehr catch Blöcken, welche Statements spezifizieren, welche eine im try Block geworfene Exception abfangen und behandeln. Das Statement versucht den try Block erfolgreich abzuarbeiten und wenn dieser nicht erfolgreich ist, wird die Kontrolle an den catch Block gegeben. Wenn ein Statement in dem try Block (oder eine im try Block aufgerufene Funktion) eine Exception wirft, wird der Kontrollfluss sofort an den catch Block übergeben. Wenn keine Exception im try Block geworfen wird, wird der catch Block übersprungen. Der optionale finally Block wird nach dem try und nach dem catch Block ausgeführt, bevor das auf das try...catch Statement folgenden Statement ausgeführt wird.

- -

Das Folgende Beispiel benutzt ein try...catch Statement. Das Beispiel ruft eine Funktion auf, welche einen Monatsnamen aus einen Array zurückgibt, je nachdem, welcher Wert übergeben wurde. Wenn der übergebene Wert keine korrekte Monatsnummer ist (1 - 12), dann wird eine Exception mit dem Wert "InvalidMonthNo" geworfen und die Statements im catch Block setzen die monthName Variable auf unknown.

- -
function getMonthName (mo) {
-  mo = mo-1; // Justiert Monatsnummer zu Arrayindex (1=Jan, 12=Dec)
-  var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul",
-                "Aug","Sep","Oct","Nov","Dec"];
-  if (months[mo] != null) {
-    return months[mo];
-  } else {
-    throw "InvalidMonthNo"; // throw Schlüsselwort wird hier benutzt
-  }
-}
-
-try { // statements to try
-  monthName = getMonthName(myMonth); // Funktion die Exceptions werfen kann
-}
-catch (e) {
-  monthName = "unknown";
-  logMyErrors(e); // Gibt Exception Objekt weiter für Fehlerbehandlung
-}
-
- -

Der catch Block

- -

Man kann einen catch Block einsetzen, um alle Exceptions, die im try Block generiert werden, zu verarbeiten.

- -
catch (catchID) {
-  statements
-}
-
- -

Der catch Block spezifiziert einen Variable (catchID im voranstehenden Syntaxbeispiel), welcher den Wert des throw Statements enthält. Man kann über diese Variable Informationen über die geworfene Exception abfragen. JavaScript erstellt diese Variable, wenn der Programmfluss in den catch Block geht. Die Variable existiert nur in dem catch Block. Nach dem beenden des catch Blocks ist die Variable nicht mehr verfügbar.

- -

Im nächsten Beispeil wird eine Exception geworfen. Wenn die Exception geworfen wird, wird der Programmfluss in den catch Block gegeben.

- -
try {
-  throw "myException" // Erstellt eine Exception
-}
-catch (e) {
-  // Statements, die die Exception verarbeiten
-  logMyErrors(e) // Verarbeitet Exception Objekt zur Fehlerbehandlung
-}
-
- -

Der finally Block

- -

Der finally Block enthält Statements, welche nach dem try und catch Block ausgeführt werden, bevor das Statement nach dem try...catch Statement ausgeführt wird. Der finally Block wird ausgeführt, egal ob eine Exception geworfen wird oder nicht. Wenn eine Exception geworfen wird, wird der finally auch ausgeführt, wenn kein catch die Exception abfängt.

- -

Man kann den finally Block benutzen, um Skripte fehlertoleranter zu gestalten. Zum Beispiel kann eine Ressource im finally Block geschlossen werden. Das Folgende Beispiel öffnet eine Datei und führt Statements aus, um die Datei zu benutzen (Serverseitiges JavaScript erlaubt Zugriffe auf Dateien). Wenn eine Exception geworfen wird, während die Datei geöffnet ist, sorgt der finally Block dafür, dass die Datei wieder geschlossen wird.

- -
openMyFile();
-try {
-  writeMyFile(theData); //Das kann Exceptions werfen
-} catch(e) {
-  handleError(e); // Wenn eine Exception geworfen wird, wird sie hier verarbeitet
-} finally {
-  closeMyFile(); // Schließt immer die Ressource
-}
-
- -

Wenn der finally Block einen Rückgabewert definiert, ist dieser der Rückgabewert des try-catch-finally Prozedur, unabhängig davon, ob return Statements im try und catch Block verwendet werden.

- -
function f() {
-  try {
-    console.log(0);
-    throw "bogus";
-  } catch(e) {
-    console.log(1);
-    return true; // Dieses return Statement is überflüssig
-                 // weil im finally Block ebenfalls eins vorhanden ist
-    console.log(2); // wird niemals erreicht
-  } finally {
-    console.log(3);
-    return false; // überschreibt früheres return Statements
-    console.log(4); // wird niemals erreicht
-  }
-  // false wird jetzt zurückgegeben
-  console.log(5); // wird niemals erreicht
-}
-f(); // alerts 0, 1, 3; returns false
-
- -

Das Überschreiben des Rückgabewertes durch den finally Block überschreibt auch geworfene Exceptions, wenn diese im catch geworfen werden.

- -
function f() {
-  try {
-    throw "bogus";
-  } catch(e) {
-    console.log('caught inner "bogus"');
-    throw e; // Dieses throw Statement is überflüssig
-             // weil im finally Block ein return vorkommt
-  } finally {
-    return false; // Überschreibt das vorherige "throw"
-  }
-  // false wird zurückgegeben
-}
-
-try {
-  f();
-} catch(e) {
-  // Dieser bereich wird nie erreicht, weil
-  // die Exception durch das return im
-  // finally block überschrieben wird.
-  console.log('caught outer "bogus"');
-}
-
-// OUTPUT
-// caught inner "bogus"
- -

Verschachtelte try...catch Statements

- -

Man kann mehrere try...catch Statements ineinander verschachteln. Wenn ein inneres try...catch Statements keinen catch Block hat, wird ein äußeres try...catch Statement mit einem catch Block eine Exception auffangen. Mehr Informationen gibt es im Kapitel Verschachtelte try-Blöcke auf der try...catch Seite.

- -

Nützliche Verwendung des Error Objekts

- -

Abhängig vom der Art des Fehlers, möchte man die Möglichkeit haben einen Namen und eine Fehlernachricht zu vergeben. 'name' und 'message' Eigenschaften sind generell durch die Klasse Error (z. B. DOMException oder Error) unterstützt. Die 'message' Eigenschaft ist dabei eine String-Repräsentation des Fehlers, so wie sie bei der Konvertierung des Objektes zu einem String benötigt wird.

- -

Wenn man beim Werfen von eigenen Exceptions die Vorteile dieser Eigenschaften nutzen möchte (wenn zum Beipsiel der catch Block nicht zwischen eigenen und System Exceptions unterscheidet), kann der Konstruktor von Error benutzt werden. Zum Beispiel:

- -
function doSomethingErrorProne () {
-  if (ourCodeMakesAMistake()) {
-    throw (new Error('The message'));
-  } else {
-    doSomethingToGetAJavascriptError();
-  }
-}
-....
-try {
-  doSomethingErrorProne();
-}
-catch (e) {
-  console.log(e.name); // logs 'Error'
-  console.log(e.message); // logs 'The message' or a JavaScript error message)
-}
- -

Promises

- -

Mit ECMAScript 6 hat JavaScript die Unterstützung für {{jsxref("Promise")}} Objekte bekommen, welche zum Steuern von asynchronen Operationen genutzt wird.

- -

Ein Promise ist in einem der folgenen Status:

- - - -

- -

Ein Bild mit XHR laden

- -

Ein einfaches Beispiel für den Einsatz von Promise und XMLHttpRequest ist das Laden eines Bildes (Siehe MDN GitHub js-examples Repository; man kann es hier auch in Aktion sehen). Jeder Schritt ist Kommentiert und erlaubt es der Architektur des Promise und XHR zu folgen. Hier ist die unkommentierte Version, welche den Promise Ablauf zeigt, zu sehen, so dass man eine Idee davon bekommt.

- -
function imgLoad(url) {
-  return new Promise(function(resolve, reject) {
-    var request = new XMLHttpRequest();
-    request.open('GET', url);
-    request.responseType = 'blob';
-    request.onload = function() {
-      if (request.status === 200) {
-        resolve(request.response);
-      } else {
-        reject(Error('Image didn\'t load successfully; error code:'
-                     + request.statusText));
-      }
-    };
-    request.onerror = function() {
-      reject(Error('There was a network error.'));
-    };
-    request.send();
-  });
-}
- -

Für deteiliertere Informationen, kann man sich die {{jsxref("Promise")}} Referenz Seite und den Using Promises Guide anschauen.

- -
{{PreviousNext("Web/JavaScript/Guide/Grammatik_und_Typen", "Web/JavaScript/Guide/Schleifen_und_Iterationen")}}
diff --git a/files/de/web/javascript/guide/loops_and_iteration/index.html b/files/de/web/javascript/guide/loops_and_iteration/index.html new file mode 100644 index 0000000000..9f351abcd9 --- /dev/null +++ b/files/de/web/javascript/guide/loops_and_iteration/index.html @@ -0,0 +1,337 @@ +--- +title: Schleifen und Iterationen +slug: Web/JavaScript/Guide/schleifen_und_iterationen +tags: + - Guide + - JavaScript + - Loop + - Syntax + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Loops_and_iteration +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}
+ +

Schleifen sind ein einfaches Werkzeug, um einzelne Schritte wiederholt auszuführen. Dieses Kapitel des JavaScript Guide stellt die verschiedenen Statements für Iterationen vor, welche in JavaScript zur Verfügung stehen.

+ +

Man kann sich Schleifen wie eine Computerversion des Spiels vorstellen, bei dem man jemandem sagt, er soll x Schritte in eine Richtung und dann y Schritte in eine andere Richtung gehen. So kann zum Beispiel die Aussage "Gehe fünf Schritte nach Osten" mit Hilfe von Schleifen so ausgedrückt werden:

+ +
var schritt;
+for (schritt = 0; schritt < 5; schritt++) {
+  // Laufe 5 mal, mit den Werten von Schritt 0 bis 4
+  console.log('Gehe einen Schritt nach Osten');
+}
+
+ +

Es gibt viele verschiedene Arten von Schleifen, doch im Wesentlichen verrichten alle die gleiche Aufgabe: sie führen eine Aktion für eine bestimmte Anzahl an Wiederholungen aus (diese Anzahl kann auch 0 sein). Dabei ermöglichen die verschiedenen Arten von Schleifen unterschiedliche Anfangs- und Endpunkte festzulegen. Es gibt zahlreiche Situationen in denen eine Art von Schleifen einfacher zum Ergebnis führt, als eine andere.

+ +

JavaScript stellt folgende Statements für Schleifen zur Verfügung:

+ + + +

for Statement

+ +

Eine  {{jsxref("statements/for","for Schleife")}} wird so lange durchlaufen, bis eine bestimmte Bedingung den Wert false liefert. Die for Schleife in JavaScript ist vergleichbar mit der in Java und C. Ein for Statement sieht wie folgt aus:

+ +
for ([initialerAusruck]; [Bedingung]; [erhöhenderAusdruck])
+  Anweisung
+
+ +

Bei der Ausführung einer for Schleife geschieht folgendes:

+ +
    +
  1. Der Ausdruck zur Initialisierung der Schleife initialerAsudruck, wird ausgeführt, sofern dieser existiert. Dieser Ausdruck initialisiert einen oder mehrere Schleifenzähler, wobei die Syntax beliebig komplexe Ausdrücke zulässt. In diesem Ausdruck können auch Variablen deklariert werden.
  2. +
  3. Die Bedingung Bedingung wird geprüft. Wenn die Auswertung von Bedingung den Wert true ergibt, werden die Anweisungen innerhalb der Schleife ausgeführt. Ergibt die Prüfung hingegen false, wird die Schleife verlassen. Bleibt die Bedingung leer, wird immer der Wert true angenommen.
  4. +
  5. Die Anweisung wird ausgeführt. Um mehrere Anweisungen auszuführen, werden Block-Anweisungen ({ ... }) verwendet, um diese zu gruppieren.
  6. +
  7. Wenn vorhanden, wird der Ausdruck erhöhenderAusdruck ausgeführt.
  8. +
  9. Geht zu Schritt 2 zurück.
  10. +
+ +

Beispiel

+ +

Die folgende Funktion enthält ein for Statement, welche die Anzahl der ausgewählten Optionen aus einer Auswahlliste (ein {{HTMLElement("select")}}, welches eine Mehrfachauswahl erlaubt) ermittelt. Das for Statement deklariert eine Variable i und initialisiert diese mit dem Wert 0. Sie prüft ob i kleiner als die Anzahl der verfügbarer Optionen des <select> Elements ist, führt das nachfolgende if Statement aus und erhöht i bei jedem Schleifendurchlauf um 1.

+ +
<form name="selectForm">
+  <p>
+    <label for="musicTypes">Choose some music types, then click the button below:</label>
+    <select id="musicTypes" name="musicTypes" multiple="multiple">
+      <option selected="selected">R&B</option>
+      <option>Jazz</option>
+      <option>Blues</option>
+      <option>New Age</option>
+      <option>Classical</option>
+      <option>Opera</option>
+    </select>
+  </p>
+  <p><input id="btn" type="button" value="How many are selected?" /></p>
+</form>
+
+<script>
+function howMany(selectObject) {
+  var numberSelected = 0;
+  for (var i = 0; i < selectObject.options.length; i++) {
+    if (selectObject.options[i].selected) {
+      numberSelected++;
+    }
+  }
+  return numberSelected;
+}
+
+var btn = document.getElementById('btn');
+btn.addEventListener('click', function(){
+  alert('Number of options selected: ' + howMany(document.selectForm.musicTypes))
+});
+</script>
+
+
+ +

do...while Statement

+ +

Das {{jsxref("statements/do...while", "do...while")}} Statement wiederholt eine bestimmte Anweisung, bis eine Bedingung false ergibt. Ein do...while Statement sieht wie folgt aus:

+ +
do
+  anweisung
+while (bedingung);
+
+ +

amweisung wird dabei einmal ausgeführt, bevor die Bedingung geprüft wird. Um mehrere Anweisungen auszuführen, werden diese als Block Statement ({ ... }) gruppiert. Wenn bedingung true ist, wird die Anweisung erneut ausgeführt. Nach jeder Ausführung der Anweisungen, wird die Bedingung erneut geprüft. Sobald bedingung false ergibt, endet die Ausführung der Schleife und die nächste Anweisung nach der do...while Schleife aus wird ausgeführt.

+ +

Beispiel

+ +

Im folgenden Beispiel wird die Schleife mindestens einmal ausgeführt. Anschliessend wird die Schleife so oft durchlaufen, bis i nicht mehr kleiner als 5 ist.

+ +
var i = 0;
+do {
+  i += 1;
+  console.log(i);
+} while (i < 5);
+ +

while Statement

+ +

Ein {{jsxref("statements/while","while")}} Statement wird solange ausgeführt, wie eine bestimmte Bedingung true ergibt. Ein while Statement sieht wie folgt aus:

+ +
while (bedingung)
+  anweisung
+
+ +

Wenn die Bedingung false ist, wird die Schleife nicht weiter durchlaufen und die nächste Anweisung nach der while Schleife wird ausgeführt.

+ +

Die Prüfung der Bedingung erfolgt, bevor die Anweisungen innerhalb der Schleife ausgeführt werden. Nur wenn die Bedingung true ist, wird die Schleife ausgeführt, wobei anschliessend eine erneute Prüfung der Bedingung erfolgt. Ergibt die Bedingung false, wir mit der Anweisungen nach der while Schleife fortgefahren.

+ +

Um mehrere Anweisungen auszuführen, werden diese in einer block Anweisung ({ ... }) gruppiert.

+ +

Beispiel 1

+ +

Die folgende while Schleife wird so lange ausgeführt, wie n kleiner als 3 ist.

+ +
var n = 0;
+var x = 0;
+while (n < 3) {
+  n++;
+  x += n;
+}
+
+ +

Mit jedem Schleifendurchlauf wird n um 1 erhöht. Der Wert von n wird dann zum Wert von x addiert. Dadurch nehmen x und n die folgenden Werte an:

+ + + +

Nach dem dritten Durchlauf ist die Bedingung n < 3 nicht mehr true und die Schleife wird verlassen.

+ +

Beispiel 2

+ +

Endlosschleifen müssen vermieden werden. Es ist immer sicherzustellen, dass die Bedingung irgendwann false ergibt, da die Schleife ansonsten nie endet. Die Anweisung in der folgenden while Schleife wird für immer ausgeführt, weil die Bedingung nie false ergibt:

+ +
while (true) {
+  console.log('Hello, world!');
+}
+ +

Label Statement

+ +

Ein {{jsxref("statements/label","label")}} stellt ein Statement mit einem Bezeichner bereit, welches es ermöglicht auf eine bestimmte stelle im Programm zu verweisen. So kann ein Label zum Beispiel dafür verwendet werden eine Schleife zu identifizieren und dann mit break oder continue festzulegen ob diese beendet oder weiter durchlaufen werden soll.

+ +

Die Syntax des Label Statement sieht wie folgt aus:

+ +
label :
+   anweisung
+
+ +

Der Wert von label kann jede Bezeichnung sein, der kein reserviertes JavaScript Schlüsselwort ist. Die anweisung die mit dem Label identifiziert wird, kann jede beliebige Anweisung sein.

+ +

Beispiel

+ +

In diesem Beispiel identifiziert das Label markLoop eine while Schleife.

+ +
markLoop:
+while (theMark == true) {
+   doSomething();
+}
+ +

break Statement

+ +

Um eine Schleife oder ein switch Statement zu beenden, verwendet man das {{jsxref("statements/break","break")}} Statement in Verbindung mit dem Label Statement.

+ + + +

Die Syntax von break sieht wie folgt aus:

+ +
break [label];
+
+ +

Die erste Variante der Syntax beendet die innerste Schleife oder das innerste switch Statement. Die zweite Variante beendet eine bestimmte Anweisung.

+ +

Beispiel 1

+ +

Das folgende Beispiel durchläuft die Elemente in einem Array, bis ein Element mit dem Wert von theValue gefunden wird:

+ +
for (var i = 0; i < a.length; i++) {
+  if (a[i] == theValue) {
+    break;
+  }
+}
+ +

Beispiel 2: break mit einem Label

+ +
var x = 0;
+var z = 0;
+labelCancelLoops: while (true) {
+  console.log('Outer loops: ' + x);
+  x += 1;
+  z = 1;
+  while (true) {
+    console.log('Inner loops: ' + z);
+    z += 1;
+    if (z === 10 && x === 10) {
+      break labelCancelLoops;
+    } else if (z === 10) {
+      break;
+    }
+  }
+}
+
+ +

continue Statement

+ +

Das {{jsxref("statements/continue","continue")}} Statement kann eingesetzt werden, um eine while, do-while, for Schleife oder ein Statement mit einem Label erneut auszuführen.

+ + + +

Die Syntax des continue Statement sieht wie folgt aus:

+ +
continue [label];
+
+ +

Beispiel 1

+ +

Das folgende Beispiel zeigt eine while Schleife, mit einem continue Statement, die weiter ausgeführt wird, wenn i den Wert 3 hat. Dadurch erhält n die Werte 1, 3, 7 und 12.

+ +
var i = 0;
+var n = 0;
+while (i < 5) {
+  i++;
+  if (i == 3) {
+    continue;
+  }
+  n += i;
+}
+
+ +

Beispiel 2

+ +

Eine Anweisung mit dem Label checkiandj enthält eine Anweisung mit dem Label checkj. Wenn continue erreicht wird, bricht das Programm den aktuellen Schleifendurchlauf von checkj ab und setzt die Ausführung beim nächsten Durchlauf fort. Immer wenn continue erreicht wird, wird checkj erneut ausgeführt, bis dessen Bedingung false zurückliefert. Wird false zurückgeliefert, wird der Rest der checkiandj Anweisung vollendet und checkiandj wird wiederholt, bis dessen Bedingung false zurückgibt. Wird false zurückgegeben, wird das Programm bei der Anweisung nach checkiandj fortgesetzt.

+ +

Wenn continue ein Label checkiandj hätte, würde das Programm am Anfang der checkiandj Anweisung fortgesetzt werden.

+ +
var i = 0;
+var j = 10;
+checkiandj:
+  while (i < 4) {
+    console.log(i);
+    i += 1;
+    checkj:
+      while (j > 4) {
+        console.log(j);
+        j -= 1;
+        if ((j % 2) == 0) {
+          continue checkj;
+        }
+        console.log(j + ' is odd.');
+      }
+      console.log('i = ' + i);
+      console.log('j = ' + j);
+  }
+ +

for...in Statement

+ +

Das {{jsxref("statements/for...in","for...in")}} Statement durchläuft eine bestimmte Variable über alle aufzählbaren Eigenschaften eines Objekts. Für jede einzelne Eigenschaft führt JavaScript die entsprechende Anweisung aus. Ein for...in Statement sieht wie folgt aus:

+ +
for (variable in object) {
+  statements
+}
+
+ +

Beispiel

+ +

Die folgende Funktion nimmt als Argument ein Objekt und dessen Namen entgegen. Anschliessend durchläuft sie alle Eigenschaften des Objekts und liefert einen String zurück, der alle Namen und Werte der Eigenschaften des Objekts enthält.

+ +
function dump_props(obj, obj_name) {
+  var result = '';
+  for (var i in obj) {
+    result += obj_name + '.' + i + ' = ' + obj[i] + '<br>';
+  }
+  result += '<hr>';
+  return result;
+}
+
+ +

Für ein Objekt car mit den Eigenschaften make und model, sieht das Ergebnis wie folgt aus:

+ +
car.make = Ford
+car.model = Mustang
+
+ +

Arrays

+ +

Auch wenn es nahe liegt diesen Weg zu verwenden, um die Elemente eines {{jsxref("Array")}}s zu durchlaufen, würde das for...in Statement die Namen der definierten Werte und den numerischen Index zurückliefern. Daher ist es besser eine normale {{jsxref("statements/for","for")}} Schleifen mit einem numerischen Index zu verwenden, wenn Arrays durchlaufen werden sollen, da das for...in Statement neben den benutzerdefinierten Elementen auch die Eigenschaften des Arrays durchläuft, wenn man Methoden oder Eigenschaften hinzufügt oder ändert.

+ +

for...of Statement

+ +

Das {{jsxref("statements/for...of","for...of")}} Statement erstellt eine Schleife, die alle iterable objects (inklusive {{jsxref("Array")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, {{jsxref("functions/arguments","arguments")}} Objekt, etc.) durchläuft und die Anweisungen ausführt, die mit dem Wert des Durchlaufes für jede Eigenschaft übereinstimmt.

+ +
for (variable of object) {
+  statement
+}
+ +

Das folgende Beispiel zeigt den Unterschied zwischen der for...of Schleife und der {{jsxref("statements/for...in","for...in")}} Schleife. Während for...in die Namen der Eigenschaften durchläuft, durchläuft for...of die Werte der Eigenschaft:

+ +
var arr = [3, 5, 7];
+arr.foo = 'hello';
+
+for (var i in arr) {
+   console.log(i); // logs "0", "1", "2", "foo"
+}
+
+for (var i of arr) {
+   console.log(i); // logs 3, 5, 7
+}
+
+ +

{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}

diff --git a/files/de/web/javascript/guide/mit_objekten_arbeiten/index.html b/files/de/web/javascript/guide/mit_objekten_arbeiten/index.html deleted file mode 100644 index 2448621a4a..0000000000 --- a/files/de/web/javascript/guide/mit_objekten_arbeiten/index.html +++ /dev/null @@ -1,506 +0,0 @@ ---- -title: Mit Objekten arbeiten -slug: Web/JavaScript/Guide/Mit_Objekten_arbeiten -tags: - - Beginner - - Comparing object - - Constructor - - Document - - Guide - - JavaScript - - Object - - 'l10n:priority' -translation_of: Web/JavaScript/Guide/Working_with_Objects ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Feinheiten_des_Objektmodells")}}
- -

JavaScript ist nach einem einfachen objekt-basierten Muster entworfen. Ein Objekt ist eine Sammlung von Eigenschaften und eine Eigenschaft ist eine Verbindung von einem Namen und einem Wert. Der Wert einer Eigenschaft kann eine Funktion sein. In diesem Fall wird die Eigenschaft Methode genannt. Zusätzlich zu Objekten, die vom Browser vordefiniert sind, können auch eigene Objekte definiert werden. Dieses Kapitel beschreibt, wie Objekte, Eigenschaften, Funktionen und Methoden benutzt und eigene Objekte erzeugt werden können.

- -

Objekte Übersicht

- -

Objekte in JavaScript, wie in vielen anderen Programmiersprachen, können mit Objekten aus dem realen Leben verglichen werden. Das Konzept der Objekte in JavaScript kann mit greifbaren Objekten aus der realen Welt verstanden werden.

- -

In JavaScript ist ein Objekt eine für sich stehende Einheit mit Eigenschaften und Typ. Vergleichbar mit einer Tasse zum Beispiel. Eine Tasse ist ein Objekt mit Eigenschaften. Eine Tasse hat eine Farbe, ein Design, ein Gewicht, ein Material, aus dem sie erstellt wurde, usw. Ebenso können JavaScript Objekte Eigenschaften besitzen, die Ihre Besonderheiten definieren.

- -

Objekte und Eigenschaften

- -

Ein JavaScript Objekt besitzt mit ihm verbundene Eigenschaften. Eine Eigenschaft eines Objekts kann als Variable erklärt werden, die dem Objekt angeheftet ist. Objekteigenschaften sind grundsätzlich das Gleiche wie übliche Variablen ausser der Verknüpfung mit Objekten. Die Eigenschaften eines Objekts definieren seine Charakteristik. Auf die Eigenschaften eines Objekt kann mit einer einfachen Punkt-Notation zugegriffen werden:

- -
objectName.propertyName
-
- -

Wie bei allen JavaScript-Variablen sind Objektname (eine normale Variable) und Attribute groß-, und kleinschreibungsabhängig. Ein Attribut wird definiert, indem es einen Wert zugewiesen bekommt. Zum Beispiel: Ein Objekt namens myCar mit den Attributen make, model, und year:

- -
var myCar = new Object();
-myCar.make = "Ford";
-myCar.model = "Mustang";
-myCar.year = 1969;
-
- -

Nicht initialisierte Eigenschaften eines Objektes haben den Wert {{jsxref("undefined")}} (nicht {{jsxref("null")}}).

- -
myCar.color; // undefined
- -

Eigenschaften von JavaScript-Objekten können auch mit der Klammernotation (für weitere Informationen siehe property accessors). Objekte werden manchmal assoziative Arrays genannt da jede Eigenschaft mit einer Zeichenkette assoziiert ist mit der man auf die Eigenschaft zugreifen kann. Zum Beispiel kann man auf die Eigenschaften des Objekts myCar folgendermassen zugreifen:

- -
myCar["make"] = "Ford";
-myCar["model"] = "Mustang";
-myCar["year"] = 1969;
-
- -

Der Name einer Objekteigenschaft kann ein valider JavaScript String sein. Dies kann auch alles sein, was in einen String convertiert werden kann, inklusive eines leeren Strings. Immer, wenn der Name einer Eigenschaft kein valider JavaScript Bezeichner ist (zum Beispiel ein Name mit einem Leerzeichen oder einem minus oder ein Name der mit einer Ziffer beginnt), kann dieses nur über die Klammernotation erreicht werden. Diese Notation ist zusätzlich sehr hilfreich, wenn Namen von Eigenschaften dynamisch ermittelt werden (Wenn die Namen nicht bis zur Laufzeit ermittelt werden können). Im folgenden ein Beispiel:

- -
// four variables are created and assigned in a single go,
-// separated by commas
-var myObj = new Object(),
-    str = 'myString',
-    rand = Math.random(),
-    obj = new Object();
-
-myObj.type              = 'Dot syntax';
-myObj['date created']   = 'String with space';
-myObj[str]              = 'String value';
-myObj[rand]             = 'Random Number';
-myObj[obj]              = 'Object';
-myObj['']               = 'Even an empty string';
-
-console.log(myObj);
-
- -

Zu bemerken ist, dass alle Schlüssel in der Klammernotation zum Typ Strings konvertiert werden, weil in JavaScript nur Strings als Schlüssel bei Objekte erlaubt sind. Zum Beispiel wird im orberen Beispiel obj konvertiert wenn es in myObj benutzt wird. JavaScript ruft die obj.toString() Methode auf und benutzt den resultierenden String als neuen Schlüssel.

- -

Man kann eine Eigenschaft auch erreichen, indem eine Variable vom Typ String benutzt wird:

- -
var propertyName = 'make';
-myCar[propertyName] = 'Ford';
-
-propertyName = 'model';
-myCar[propertyName] = 'Mustang';
-
- -

Man kann die Klammernotation mit for...in nutzen, um über alle enumerable (aufzählbaren) Eigenschaften eines Objektes zu iterieren. Um dieses zu zeigen wie das funktioniert, zeigt die folgende Funktion die Eigenschaften eines Objektes, wenn eine Objekt und der Name des Objektes der Funktion als Parameter übergeben werden:

- -
function showProps(obj, objName) {
-  var result = '';
-  for (var i in obj) {
-    // obj.hasOwnProperty() wird benutzt um Eigenschaften aus der Prototypen-Kette herauszufiltern
-    if (obj.hasOwnProperty(i)) {
-      result += objName + '.' + i + ' = ' + obj[i] + '\n';
-    }
-  }
-  return result;
-}
-
- -

So gibt der Aufruf showProps(myCar, "myCar") folgenden Rückgabewert zurück:

- -
myCar.make = Ford
-myCar.model = Mustang
-myCar.year = 1969
- -

Enumerate the properties of an object

- -

Starting with ECMAScript 5, there are three native ways to list/traverse object properties:

- - - -

Before ECMAScript 5, there was no native way to list all properties of an object. However, this can be achieved with the following function:

- -
function listAllProperties(o) {
-	var objectToInspect;
-	var result = [];
-
-	for(objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect)) {
-      result = result.concat(Object.getOwnPropertyNames(objectToInspect));
-	}
-
-	return result;
-}
-
- -

This can be useful to reveal "hidden" properties (properties in the prototype chain which are not accessible through the object, because another property has the same name earlier in the prototype chain). Listing accessible properties only can easily be done by removing duplicates in the array.

- -

Creating new objects

- -

JavaScript has a number of predefined objects. In addition, you can create your own objects. You can create an object using an object initializer. Alternatively, you can first create a constructor function and then instantiate an object invoking that function in conjunction with the new operator.

- -

Using object initializers

- -

In addition to creating objects using a constructor function, you can create objects using an object initializer. Using object initializers is sometimes referred to as creating objects with literal notation. "Object initializer" is consistent with the terminology used by C++.

- -

The syntax for an object using an object initializer is:

- -
var obj = { property_1:   value_1,   // property_# may be an identifier...
-            2:            value_2,   // or a number...
-            // ...,
-            'property n': value_n }; // or a string
-
- -

where obj is the name of the new object, each property_i is an identifier (either a name, a number, or a string literal), and each value_i is an expression whose value is assigned to the property_i. The obj and assignment is optional; if you do not need to refer to this object elsewhere, you do not need to assign it to a variable. (Note that you may need to wrap the object literal in parentheses if the object appears where a statement is expected, so as not to have the literal be confused with a block statement.)

- -

Object initializers are expressions, and each object initializer results in a new object being created whenever the statement in which it appears is executed. Identical object initializers create distinct objects that will not compare to each other as equal. Objects are created as if a call to new Object() were made; that is, objects made from object literal expressions are instances of Object.

- -

The following statement creates an object and assigns it to the variable x if and only if the expression cond is true:

- -
if (cond) var x = {greeting: 'hi there'};
-
- -

The following example creates myHonda with three properties. Note that the engine property is also an object with its own properties.

- -
var myHonda = {color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}};
-
- -

You can also use object initializers to create arrays. See array literals.

- -

Using a constructor function

- -

Alternatively, you can create an object with these two steps:

- -
    -
  1. Define the object type by writing a constructor function. There is a strong convention, with good reason, to use a capital initial letter.
  2. -
  3. Create an instance of the object with new.
  4. -
- -

To define an object type, create a function for the object type that specifies its name, properties, and methods. For example, suppose you want to create an object type for cars. You want this type of object to be called Car, and you want it to have properties for make, model, and year. To do this, you would write the following function:

- -
function Car(make, model, year) {
-  this.make = make;
-  this.model = model;
-  this.year = year;
-}
-
- -

Notice the use of this to assign values to the object's properties based on the values passed to the function.

- -

Now you can create an object called mycar as follows:

- -
var mycar = new Car('Eagle', 'Talon TSi', 1993);
-
- -

This statement creates mycar and assigns it the specified values for its properties. Then the value of mycar.make is the string "Eagle", mycar.year is the integer 1993, and so on.

- -

You can create any number of Car objects by calls to new. For example,

- -
var kenscar = new Car('Nissan', '300ZX', 1992);
-var vpgscar = new Car('Mazda', 'Miata', 1990);
-
- -

An object can have a property that is itself another object. For example, suppose you define an object called person as follows:

- -
function Person(name, age, sex) {
-  this.name = name;
-  this.age = age;
-  this.sex = sex;
-}
-
- -

and then instantiate two new person objects as follows:

- -
var rand = new Person('Rand McKinnon', 33, 'M');
-var ken = new Person('Ken Jones', 39, 'M');
-
- -

Then, you can rewrite the definition of Car to include an owner property that takes a person object, as follows:

- -
function Car(make, model, year, owner) {
-  this.make = make;
-  this.model = model;
-  this.year = year;
-  this.owner = owner;
-}
-
- -

To instantiate the new objects, you then use the following:

- -
var car1 = new Car('Eagle', 'Talon TSi', 1993, rand);
-var car2 = new Car('Nissan', '300ZX', 1992, ken);
-
- -

Notice that instead of passing a literal string or integer value when creating the new objects, the above statements pass the objects rand and ken as the arguments for the owners. Then if you want to find out the name of the owner of car2, you can access the following property:

- -
car2.owner.name
-
- -

Note that you can always add a property to a previously defined object. For example, the statement

- -
car1.color = 'black';
-
- -

adds a property color to car1, and assigns it a value of "black." However, this does not affect any other objects. To add the new property to all objects of the same type, you have to add the property to the definition of the Car object type.

- -

Using the Object.create method

- -

Objects can also be created using the {{jsxref("Object.create()")}} method. This method can be very useful, because it allows you to choose the prototype object for the object you want to create, without having to define a constructor function.

- -
// Animal properties and method encapsulation
-var Animal = {
-  type: 'Invertebrates', // Default value of properties
-  displayType: function() {  // Method which will display type of Animal
-    console.log(this.type);
-  }
-};
-
-// Create new animal type called animal1
-var animal1 = Object.create(Animal);
-animal1.displayType(); // Output:Invertebrates
-
-// Create new animal type called Fishes
-var fish = Object.create(Animal);
-fish.type = 'Fishes';
-fish.displayType(); // Output:Fishes
- -

Inheritance

- -

All objects in JavaScript inherit from at least one other object. The object being inherited from is known as the prototype, and the inherited properties can be found in the prototype object of the constructor. See Inheritance and the prototype chain for more information.

- -

Indexing object properties

- -

You can refer to a property of an object either by its property name or by its ordinal index. If you initially define a property by its name, you must always refer to it by its name, and if you initially define a property by an index, you must always refer to it by its index.

- -

This restriction applies when you create an object and its properties with a constructor function (as we did previously with the Car object type) and when you define individual properties explicitly (for example, myCar.color = "red"). If you initially define an object property with an index, such as myCar[5] = "25 mpg", you subsequently refer to the property only as myCar[5].

- -

The exception to this rule is objects reflected from HTML, such as the forms array. You can always refer to objects in these arrays by either their ordinal number (based on where they appear in the document) or their name (if defined). For example, if the second <FORM> tag in a document has a NAME attribute of "myForm", you can refer to the form as document.forms[1] or document.forms["myForm"] or document.forms.myForm.

- -

Defining properties for an object type

- -

You can add a property to a previously defined object type by using the prototype property. This defines a property that is shared by all objects of the specified type, rather than by just one instance of the object. The following code adds a color property to all objects of type Car, and then assigns a value to the color property of the object car1.

- -
Car.prototype.color = null;
-car1.color = 'black';
-
- -

See the prototype property of the Function object in the JavaScript reference for more information.

- -

Defining methods

- -

A method is a function associated with an object, or, simply put, a method is a property of an object that is a function. Methods are defined the way normal functions are defined, except that they have to be assigned as the property of an object. See also method definitions for more details. An example is:

- -
objectName.methodname = functionName;
-
-var myObj = {
-  myMethod: function(params) {
-    // ...do something
-  }
-
-  // OR THIS WORKS TOO
-
-  myOtherMethod(params) {
-    // ...do something else
-  }
-};
-
- -

where objectName is an existing object, methodname is the name you are assigning to the method, and functionName is the name of the function.

- -

You can then call the method in the context of the object as follows:

- -
object.methodname(params);
-
- -

You can define methods for an object type by including a method definition in the object constructor function. You could define a function that would format and display the properties of the previously-defined Car objects; for example,

- -
function displayCar() {
-  var result = 'A Beautiful ' + this.year + ' ' + this.make
-    + ' ' + this.model;
-  pretty_print(result);
-}
-
- -

where pretty_print is a function to display a horizontal rule and a string. Notice the use of this to refer to the object to which the method belongs.

- -

You can make this function a method of Car by adding the statement

- -
this.displayCar = displayCar;
-
- -

to the object definition. So, the full definition of Car would now look like

- -
function Car(make, model, year, owner) {
-  this.make = make;
-  this.model = model;
-  this.year = year;
-  this.owner = owner;
-  this.displayCar = displayCar;
-}
-
- -

Then you can call the displayCar method for each of the objects as follows:

- -
car1.displayCar();
-car2.displayCar();
-
- -

Using this for object references

- -

JavaScript has a special keyword, this, that you can use within a method to refer to the current object. For example, suppose you have a function called validate that validates an object's value property, given the object and the high and low values:

- -
function validate(obj, lowval, hival) {
-  if ((obj.value < lowval) || (obj.value > hival)) {
-    alert('Invalid Value!');
-  }
-}
-
- -

Then, you could call validate in each form element's onchange event handler, using this to pass it the element, as in the following example:

- -
<input type="text" name="age" size="3"
-  onChange="validate(this, 18, 99)">
-
- -

In general, this refers to the calling object in a method.

- -

When combined with the form property, this can refer to the current object's parent form. In the following example, the form myForm contains a Text object and a button. When the user clicks the button, the value of the Text object is set to the form's name. The button's onclick event handler uses this.form to refer to the parent form, myForm.

- -
<form name="myForm">
-<p><label>Form name:<input type="text" name="text1" value="Beluga"></label>
-<p><input name="button1" type="button" value="Show Form Name"
-     onclick="this.form.text1.value = this.form.name">
-</p>
-</form>
- -

Defining getters and setters

- -

A getter is a method that gets the value of a specific property. A setter is a method that sets the value of a specific property. You can define getters and setters on any predefined core object or user-defined object that supports the addition of new properties. The syntax for defining getters and setters uses the object literal syntax.

- -

The following illustrates how getters and setters could work for a user-defined object o.

- -
var o = {
-  a: 7,
-  get b() {
-    return this.a + 1;
-  },
-  set c(x) {
-    this.a = x / 2;
-  }
-};
-
-console.log(o.a); // 7
-console.log(o.b); // 8
-o.c = 50;
-console.log(o.a); // 25
-
- -

The o object's properties are:

- - - -

Please note that function names of getters and setters defined in an object literal using "[gs]et property()" (as opposed to __define[GS]etter__ ) are not the names of the getters themselves, even though the [gs]et propertyName(){ } syntax may mislead you to think otherwise. To name a function in a getter or setter using the "[gs]et property()" syntax, define an explicitly named function programmatically using Object.defineProperty (or the Object.prototype.__defineGetter__ legacy fallback).

- -

The following code illustrates how getters and setters can extend the {{jsxref("Date")}} prototype to add a year property to all instances of the predefined Date class. It uses the Date class's existing getFullYear and setFullYear methods to support the year property's getter and setter.

- -

These statements define a getter and setter for the year property:

- -
var d = Date.prototype;
-Object.defineProperty(d, 'year', {
-  get: function() { return this.getFullYear(); },
-  set: function(y) { this.setFullYear(y); }
-});
-
- -

These statements use the getter and setter in a Date object:

- -
var now = new Date();
-console.log(now.year); // 2000
-now.year = 2001; // 987617605170
-console.log(now);
-// Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
-
- -

In principle, getters and setters can be either

- - - -

When defining getters and setters using object initializers all you need to do is to prefix a getter method with get and a setter method with set. Of course, the getter method must not expect a parameter, while the setter method expects exactly one parameter (the new value to set). For instance:

- -
var o = {
-  a: 7,
-  get b() { return this.a + 1; },
-  set c(x) { this.a = x / 2; }
-};
-
- -

Getters and setters can also be added to an object at any time after creation using the Object.defineProperties method. This method's first parameter is the object on which you want to define the getter or setter. The second parameter is an object whose property names are the getter or setter names, and whose property values are objects for defining the getter or setter functions. Here's an example that defines the same getter and setter used in the previous example:

- -
var o = { a: 0 };
-
-Object.defineProperties(o, {
-    'b': { get: function() { return this.a + 1; } },
-    'c': { set: function(x) { this.a = x / 2; } }
-});
-
-o.c = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
-console.log(o.b); // Runs the getter, which yields a + 1 or 6
-
- -

Which of the two forms to choose depends on your programming style and task at hand. If you already go for the object initializer when defining a prototype you will probably most of the time choose the first form. This form is more compact and natural. However, if you need to add getters and setters later — because you did not write the prototype or particular object — then the second form is the only possible form. The second form probably best represents the dynamic nature of JavaScript — but it can make the code hard to read and understand.

- -

Deleting properties

- -

You can remove a non-inherited property by using the delete operator. The following code shows how to remove a property.

- -
// Creates a new object, myobj, with two properties, a and b.
-var myobj = new Object;
-myobj.a = 5;
-myobj.b = 12;
-
-// Removes the a property, leaving myobj with only the b property.
-delete myobj.a;
-console.log ('a' in myobj); // yields "false"
-
- -

You can also use delete to delete a global variable if the var keyword was not used to declare the variable:

- -
g = 17;
-delete g;
-
- -

Comparing Objects

- -

In JavaScript objects are a reference type. Two distinct objects are never equal, even if they have the same properties. Only comparing the same object reference with itself yields true.

- -
// Two variables, two distinct objects with the same properties
-var fruit = {name: 'apple'};
-var fruitbear = {name: 'apple'};
-
-fruit == fruitbear; // return false
-fruit === fruitbear; // return false
- -
// Two variables, a single object
-var fruit = {name: 'apple'};
-var fruitbear = fruit;  // assign fruit object reference to fruitbear
-
-// here fruit and fruitbear are pointing to same object
-fruit == fruitbear; // return true
-fruit === fruitbear; // return true
-
- -
fruit.name = 'grape';
-console.log(fruitbear);    // yields { name: "grape" } instead of { name: "apple" }
-
- -

For more information about comparison operators, see Comparison operators.

- -

See also

- - - -

{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Feinheiten_des_Objektmodells")}}

diff --git a/files/de/web/javascript/guide/schleifen_und_iterationen/index.html b/files/de/web/javascript/guide/schleifen_und_iterationen/index.html deleted file mode 100644 index 9f351abcd9..0000000000 --- a/files/de/web/javascript/guide/schleifen_und_iterationen/index.html +++ /dev/null @@ -1,337 +0,0 @@ ---- -title: Schleifen und Iterationen -slug: Web/JavaScript/Guide/schleifen_und_iterationen -tags: - - Guide - - JavaScript - - Loop - - Syntax - - 'l10n:priority' -translation_of: Web/JavaScript/Guide/Loops_and_iteration ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}
- -

Schleifen sind ein einfaches Werkzeug, um einzelne Schritte wiederholt auszuführen. Dieses Kapitel des JavaScript Guide stellt die verschiedenen Statements für Iterationen vor, welche in JavaScript zur Verfügung stehen.

- -

Man kann sich Schleifen wie eine Computerversion des Spiels vorstellen, bei dem man jemandem sagt, er soll x Schritte in eine Richtung und dann y Schritte in eine andere Richtung gehen. So kann zum Beispiel die Aussage "Gehe fünf Schritte nach Osten" mit Hilfe von Schleifen so ausgedrückt werden:

- -
var schritt;
-for (schritt = 0; schritt < 5; schritt++) {
-  // Laufe 5 mal, mit den Werten von Schritt 0 bis 4
-  console.log('Gehe einen Schritt nach Osten');
-}
-
- -

Es gibt viele verschiedene Arten von Schleifen, doch im Wesentlichen verrichten alle die gleiche Aufgabe: sie führen eine Aktion für eine bestimmte Anzahl an Wiederholungen aus (diese Anzahl kann auch 0 sein). Dabei ermöglichen die verschiedenen Arten von Schleifen unterschiedliche Anfangs- und Endpunkte festzulegen. Es gibt zahlreiche Situationen in denen eine Art von Schleifen einfacher zum Ergebnis führt, als eine andere.

- -

JavaScript stellt folgende Statements für Schleifen zur Verfügung:

- - - -

for Statement

- -

Eine  {{jsxref("statements/for","for Schleife")}} wird so lange durchlaufen, bis eine bestimmte Bedingung den Wert false liefert. Die for Schleife in JavaScript ist vergleichbar mit der in Java und C. Ein for Statement sieht wie folgt aus:

- -
for ([initialerAusruck]; [Bedingung]; [erhöhenderAusdruck])
-  Anweisung
-
- -

Bei der Ausführung einer for Schleife geschieht folgendes:

- -
    -
  1. Der Ausdruck zur Initialisierung der Schleife initialerAsudruck, wird ausgeführt, sofern dieser existiert. Dieser Ausdruck initialisiert einen oder mehrere Schleifenzähler, wobei die Syntax beliebig komplexe Ausdrücke zulässt. In diesem Ausdruck können auch Variablen deklariert werden.
  2. -
  3. Die Bedingung Bedingung wird geprüft. Wenn die Auswertung von Bedingung den Wert true ergibt, werden die Anweisungen innerhalb der Schleife ausgeführt. Ergibt die Prüfung hingegen false, wird die Schleife verlassen. Bleibt die Bedingung leer, wird immer der Wert true angenommen.
  4. -
  5. Die Anweisung wird ausgeführt. Um mehrere Anweisungen auszuführen, werden Block-Anweisungen ({ ... }) verwendet, um diese zu gruppieren.
  6. -
  7. Wenn vorhanden, wird der Ausdruck erhöhenderAusdruck ausgeführt.
  8. -
  9. Geht zu Schritt 2 zurück.
  10. -
- -

Beispiel

- -

Die folgende Funktion enthält ein for Statement, welche die Anzahl der ausgewählten Optionen aus einer Auswahlliste (ein {{HTMLElement("select")}}, welches eine Mehrfachauswahl erlaubt) ermittelt. Das for Statement deklariert eine Variable i und initialisiert diese mit dem Wert 0. Sie prüft ob i kleiner als die Anzahl der verfügbarer Optionen des <select> Elements ist, führt das nachfolgende if Statement aus und erhöht i bei jedem Schleifendurchlauf um 1.

- -
<form name="selectForm">
-  <p>
-    <label for="musicTypes">Choose some music types, then click the button below:</label>
-    <select id="musicTypes" name="musicTypes" multiple="multiple">
-      <option selected="selected">R&B</option>
-      <option>Jazz</option>
-      <option>Blues</option>
-      <option>New Age</option>
-      <option>Classical</option>
-      <option>Opera</option>
-    </select>
-  </p>
-  <p><input id="btn" type="button" value="How many are selected?" /></p>
-</form>
-
-<script>
-function howMany(selectObject) {
-  var numberSelected = 0;
-  for (var i = 0; i < selectObject.options.length; i++) {
-    if (selectObject.options[i].selected) {
-      numberSelected++;
-    }
-  }
-  return numberSelected;
-}
-
-var btn = document.getElementById('btn');
-btn.addEventListener('click', function(){
-  alert('Number of options selected: ' + howMany(document.selectForm.musicTypes))
-});
-</script>
-
-
- -

do...while Statement

- -

Das {{jsxref("statements/do...while", "do...while")}} Statement wiederholt eine bestimmte Anweisung, bis eine Bedingung false ergibt. Ein do...while Statement sieht wie folgt aus:

- -
do
-  anweisung
-while (bedingung);
-
- -

amweisung wird dabei einmal ausgeführt, bevor die Bedingung geprüft wird. Um mehrere Anweisungen auszuführen, werden diese als Block Statement ({ ... }) gruppiert. Wenn bedingung true ist, wird die Anweisung erneut ausgeführt. Nach jeder Ausführung der Anweisungen, wird die Bedingung erneut geprüft. Sobald bedingung false ergibt, endet die Ausführung der Schleife und die nächste Anweisung nach der do...while Schleife aus wird ausgeführt.

- -

Beispiel

- -

Im folgenden Beispiel wird die Schleife mindestens einmal ausgeführt. Anschliessend wird die Schleife so oft durchlaufen, bis i nicht mehr kleiner als 5 ist.

- -
var i = 0;
-do {
-  i += 1;
-  console.log(i);
-} while (i < 5);
- -

while Statement

- -

Ein {{jsxref("statements/while","while")}} Statement wird solange ausgeführt, wie eine bestimmte Bedingung true ergibt. Ein while Statement sieht wie folgt aus:

- -
while (bedingung)
-  anweisung
-
- -

Wenn die Bedingung false ist, wird die Schleife nicht weiter durchlaufen und die nächste Anweisung nach der while Schleife wird ausgeführt.

- -

Die Prüfung der Bedingung erfolgt, bevor die Anweisungen innerhalb der Schleife ausgeführt werden. Nur wenn die Bedingung true ist, wird die Schleife ausgeführt, wobei anschliessend eine erneute Prüfung der Bedingung erfolgt. Ergibt die Bedingung false, wir mit der Anweisungen nach der while Schleife fortgefahren.

- -

Um mehrere Anweisungen auszuführen, werden diese in einer block Anweisung ({ ... }) gruppiert.

- -

Beispiel 1

- -

Die folgende while Schleife wird so lange ausgeführt, wie n kleiner als 3 ist.

- -
var n = 0;
-var x = 0;
-while (n < 3) {
-  n++;
-  x += n;
-}
-
- -

Mit jedem Schleifendurchlauf wird n um 1 erhöht. Der Wert von n wird dann zum Wert von x addiert. Dadurch nehmen x und n die folgenden Werte an:

- - - -

Nach dem dritten Durchlauf ist die Bedingung n < 3 nicht mehr true und die Schleife wird verlassen.

- -

Beispiel 2

- -

Endlosschleifen müssen vermieden werden. Es ist immer sicherzustellen, dass die Bedingung irgendwann false ergibt, da die Schleife ansonsten nie endet. Die Anweisung in der folgenden while Schleife wird für immer ausgeführt, weil die Bedingung nie false ergibt:

- -
while (true) {
-  console.log('Hello, world!');
-}
- -

Label Statement

- -

Ein {{jsxref("statements/label","label")}} stellt ein Statement mit einem Bezeichner bereit, welches es ermöglicht auf eine bestimmte stelle im Programm zu verweisen. So kann ein Label zum Beispiel dafür verwendet werden eine Schleife zu identifizieren und dann mit break oder continue festzulegen ob diese beendet oder weiter durchlaufen werden soll.

- -

Die Syntax des Label Statement sieht wie folgt aus:

- -
label :
-   anweisung
-
- -

Der Wert von label kann jede Bezeichnung sein, der kein reserviertes JavaScript Schlüsselwort ist. Die anweisung die mit dem Label identifiziert wird, kann jede beliebige Anweisung sein.

- -

Beispiel

- -

In diesem Beispiel identifiziert das Label markLoop eine while Schleife.

- -
markLoop:
-while (theMark == true) {
-   doSomething();
-}
- -

break Statement

- -

Um eine Schleife oder ein switch Statement zu beenden, verwendet man das {{jsxref("statements/break","break")}} Statement in Verbindung mit dem Label Statement.

- - - -

Die Syntax von break sieht wie folgt aus:

- -
break [label];
-
- -

Die erste Variante der Syntax beendet die innerste Schleife oder das innerste switch Statement. Die zweite Variante beendet eine bestimmte Anweisung.

- -

Beispiel 1

- -

Das folgende Beispiel durchläuft die Elemente in einem Array, bis ein Element mit dem Wert von theValue gefunden wird:

- -
for (var i = 0; i < a.length; i++) {
-  if (a[i] == theValue) {
-    break;
-  }
-}
- -

Beispiel 2: break mit einem Label

- -
var x = 0;
-var z = 0;
-labelCancelLoops: while (true) {
-  console.log('Outer loops: ' + x);
-  x += 1;
-  z = 1;
-  while (true) {
-    console.log('Inner loops: ' + z);
-    z += 1;
-    if (z === 10 && x === 10) {
-      break labelCancelLoops;
-    } else if (z === 10) {
-      break;
-    }
-  }
-}
-
- -

continue Statement

- -

Das {{jsxref("statements/continue","continue")}} Statement kann eingesetzt werden, um eine while, do-while, for Schleife oder ein Statement mit einem Label erneut auszuführen.

- - - -

Die Syntax des continue Statement sieht wie folgt aus:

- -
continue [label];
-
- -

Beispiel 1

- -

Das folgende Beispiel zeigt eine while Schleife, mit einem continue Statement, die weiter ausgeführt wird, wenn i den Wert 3 hat. Dadurch erhält n die Werte 1, 3, 7 und 12.

- -
var i = 0;
-var n = 0;
-while (i < 5) {
-  i++;
-  if (i == 3) {
-    continue;
-  }
-  n += i;
-}
-
- -

Beispiel 2

- -

Eine Anweisung mit dem Label checkiandj enthält eine Anweisung mit dem Label checkj. Wenn continue erreicht wird, bricht das Programm den aktuellen Schleifendurchlauf von checkj ab und setzt die Ausführung beim nächsten Durchlauf fort. Immer wenn continue erreicht wird, wird checkj erneut ausgeführt, bis dessen Bedingung false zurückliefert. Wird false zurückgeliefert, wird der Rest der checkiandj Anweisung vollendet und checkiandj wird wiederholt, bis dessen Bedingung false zurückgibt. Wird false zurückgegeben, wird das Programm bei der Anweisung nach checkiandj fortgesetzt.

- -

Wenn continue ein Label checkiandj hätte, würde das Programm am Anfang der checkiandj Anweisung fortgesetzt werden.

- -
var i = 0;
-var j = 10;
-checkiandj:
-  while (i < 4) {
-    console.log(i);
-    i += 1;
-    checkj:
-      while (j > 4) {
-        console.log(j);
-        j -= 1;
-        if ((j % 2) == 0) {
-          continue checkj;
-        }
-        console.log(j + ' is odd.');
-      }
-      console.log('i = ' + i);
-      console.log('j = ' + j);
-  }
- -

for...in Statement

- -

Das {{jsxref("statements/for...in","for...in")}} Statement durchläuft eine bestimmte Variable über alle aufzählbaren Eigenschaften eines Objekts. Für jede einzelne Eigenschaft führt JavaScript die entsprechende Anweisung aus. Ein for...in Statement sieht wie folgt aus:

- -
for (variable in object) {
-  statements
-}
-
- -

Beispiel

- -

Die folgende Funktion nimmt als Argument ein Objekt und dessen Namen entgegen. Anschliessend durchläuft sie alle Eigenschaften des Objekts und liefert einen String zurück, der alle Namen und Werte der Eigenschaften des Objekts enthält.

- -
function dump_props(obj, obj_name) {
-  var result = '';
-  for (var i in obj) {
-    result += obj_name + '.' + i + ' = ' + obj[i] + '<br>';
-  }
-  result += '<hr>';
-  return result;
-}
-
- -

Für ein Objekt car mit den Eigenschaften make und model, sieht das Ergebnis wie folgt aus:

- -
car.make = Ford
-car.model = Mustang
-
- -

Arrays

- -

Auch wenn es nahe liegt diesen Weg zu verwenden, um die Elemente eines {{jsxref("Array")}}s zu durchlaufen, würde das for...in Statement die Namen der definierten Werte und den numerischen Index zurückliefern. Daher ist es besser eine normale {{jsxref("statements/for","for")}} Schleifen mit einem numerischen Index zu verwenden, wenn Arrays durchlaufen werden sollen, da das for...in Statement neben den benutzerdefinierten Elementen auch die Eigenschaften des Arrays durchläuft, wenn man Methoden oder Eigenschaften hinzufügt oder ändert.

- -

for...of Statement

- -

Das {{jsxref("statements/for...of","for...of")}} Statement erstellt eine Schleife, die alle iterable objects (inklusive {{jsxref("Array")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, {{jsxref("functions/arguments","arguments")}} Objekt, etc.) durchläuft und die Anweisungen ausführt, die mit dem Wert des Durchlaufes für jede Eigenschaft übereinstimmt.

- -
for (variable of object) {
-  statement
-}
- -

Das folgende Beispiel zeigt den Unterschied zwischen der for...of Schleife und der {{jsxref("statements/for...in","for...in")}} Schleife. Während for...in die Namen der Eigenschaften durchläuft, durchläuft for...of die Werte der Eigenschaft:

- -
var arr = [3, 5, 7];
-arr.foo = 'hello';
-
-for (var i in arr) {
-   console.log(i); // logs "0", "1", "2", "foo"
-}
-
-for (var i of arr) {
-   console.log(i); // logs 3, 5, 7
-}
-
- -

{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}

diff --git a/files/de/web/javascript/guide/text_formatting/index.html b/files/de/web/javascript/guide/text_formatting/index.html new file mode 100644 index 0000000000..48c45c9871 --- /dev/null +++ b/files/de/web/javascript/guide/text_formatting/index.html @@ -0,0 +1,257 @@ +--- +title: Textformatierung +slug: Web/JavaScript/Guide/Textformatierung +tags: + - Guide + - JavaScript + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Text_formatting +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}
+ +

Dieses Kapitel gibt eine Einführung darüber, wie in JavaScript mit Strings (Zeichenfolgen) und Texten gearbeitet wird.

+ +

Strings

+ +

JavaScript's Datentyp {{Glossary("String")}} wird verwendet, um textuelle Daten zu repräsentieren. Es handelt sich um eine Reihe von Elementen, die ganzzahlige 16-Bit-Werte ohne Vorzeichen (UTF-16 Code Units) sind. Jedes Element belegt eine Position im String. Das erste Element befindet hat den Index 0, das nächste den Index 1 usw. Die Länge des Strings ist die Anzahl der Elemente, die darin enthalten sind. Strings können über String-Literale oder String-Objekte erzeugt werden.

+ +

ACHTUNG: Beim Bearbeiten dieser Seite keine Zeichen mit Zeichencode größer als U+FFFF einfügen, bis MDN bug 857438 behoben wurde ( https://bugzilla.mozilla.org/show_bug.cgi?id=857438 ).

+ +

String Literale

+ +

Einfache Strings können mittels einfacher oder doppelter Anführungszeichen erzeugt werden:

+ +
'foo'
+"bar"
+ +

Anspruchsvollere Strings können mit Escape-Sequenzen erstellt werden:

+ +

Hexadezimale Escape-Sequenzen

+ +

Die Zahl nach \x wird als hexadecimale Zahl interpretiert.

+ +
'\xA9' // "©"
+
+ +

Unicode Escape-Sequenzen

+ +

Unicode Escape-Sequenzen erfordern mindestens vier hexadezimale Ziffern nach \u.

+ +
'\u00A9' // "©"
+ +

Unicode Code Point Escapes

+ +

Diese sind neu in ECMAScript 2015. Mit Unicode Code Point Maskierung können beliebige Zeichen durch Maskierungssequenzen mit hexadezimalen Zahlen erzeugt werden, sodass die Verwendung von Unicode Code Points bis zu 0x10FFFF möglich ist. Mit einfachen Unicode Maskierungssequenz ist es oft notwendig, Surrogate-Hälften als zwei getrennte Maskierungssequenzen zu schreiben, um dasselbe Ergebnis zu erhalten.

+ +

Siehe auch {{jsxref("String.fromCodePoint()")}} oder {{jsxref("String.prototype.codePointAt()")}}.

+ +
'\u{2F804}'
+
+// das gleiche mit einfachen Unicode Escape-Sequenzen
+'\uD87E\uDC04'
+ +

String Objekte

+ +

Das {{jsxref("String")}} Objekt ist ein Wrapper für den primitiven Datentyp String.

+ +
var s = new String('foo'); // Erstellt ein String object
+console.log(s); // Ausgabe: {'0': 'f', '1': 'o', '2': 'o'}
+typeof s; // Gibt 'object' zurück
+
+ +

Beliebige Methoden des String Objekts können als Methoden eines String-Literals aufgerufen werden – JavaScript wandelt das String-Literal automatisch in ein temporäres String Objekt um, ruft die Methode auf und verwirft das temporäre String Objekt anschließend. Außerdem kann die String.length Eigenschaft mit einem String-Literal verwendet werden.

+ +

String-Literale sollten verwendet werden, außer es wird tatsächlich ein String Objekt benötigt, da String Objekte unerwartetes Verhalten aufweisen können. Beispielsweise:

+ +
var s1 = '2 + 2'; // Erzeugt ein String-Literal
+var s2 = new String('2 + 2'); // Erzeugt ein String Objekt
+eval(s1); // Gibt die Zahl 4 zurück
+eval(s2); // Gibt den String "2 + 2" zurück
+ +

Ein String Objekt hat eine Eigenschaft length, die die Anzahl von der UTF-16 Code Units im String angibt. Der folgende Code beispielsweise weist der Variable x den Wert 13 zu, da "Hello, World!" aus 13 Zeichen besteht. Jedes dieser Zeichen wird durch eine UTF-16 Code Unit dargestellt. Auf jede dieser Code Units kann durch eckige Klammern zugegriffen werden. Es können jedoch keine Zeichen geändert werden, da Strings unveränderbare Array-ähnliche Objekte sind:

+ +
var mystring = 'Hello, World!';
+var x = mystring.length;
+mystring[0] = 'L'; // hat keinen Effekt
+mystring[0]; // gibt "H" zurück
+
+ +

Zeichen mit einem Unicode-Wert größer als U+FFFF (wie z.B. manche seltene chinesiche/japanische/koreanische/vietnamesische Zeichen und einige Emoji) werden in UTF-16 als zwei Surrogate Code Units gespeichert. Ein String, der nur aus einem Zeichen, U+1F600 ("Emoji grinning face"), besteht, hätte die Länge 2. Der Zugriff auf einzelne Code Units in einem solchen String kann zu unerwünschten Effekten führen, wie z.B. die Entstehung von String mit unvollständigen Surrogate Code Units, was gegen den Unicode Standard verstößt. (Beispiele dafür sollten zu dieser Seite hinzugefügt werden, sobald MDN bug 857438 behoben wurde.) Siehe auch {{jsxref("String.fromCodePoint()")}} oder {{jsxref("String.prototype.codePointAt()")}}.

+ +

Ein String Objekt verschiedenste Methoden, unter anderem auch welche, die den String in abgewandelter Form zurückgeben, wie z.B. substring und toUpperCase.

+ +

Die folgende Tabelle gibt eine Zusammenfassung der Methoden von {{jsxref("String")}} Objekten.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Methoden von String

+
MethodeBeschreibung
{{jsxref("String.charAt", "charAt")}}, {{jsxref("String.charCodeAt", "charCodeAt")}}, {{jsxref("String.codePointAt", "codePointAt")}}Gibt das Zeichen oder den Zeichencode an der angegebenen Stelle im String zurück.
{{jsxref("String.indexOf", "indexOf")}}, {{jsxref("String.lastIndexOf", "lastIndexOf")}}Gibt die erste bzw. letzte Position des angegebenen Teilstrings im String zurück.
{{jsxref("String.startsWith", "startsWith")}}, {{jsxref("String.endsWith", "endsWith")}}, {{jsxref("String.includes", "includes")}}Gibt zurück, ob ein String mit dem angegebenen Teilstring beginnt, endet oder den Teilstring enthält.
{{jsxref("String.concat", "concat")}}Fügt die beiden Strings zusammen und gibt diesen neuen String zurück.
{{jsxref("String.fromCharCode", "fromCharCode")}}, {{jsxref("String.fromCodePoint", "fromCodePoint")}}Erstellt einen String aus den angegebenen Unicode Codes. Es handelt sich um eine Methode der Klasse String, nicht die einer String Instanz.
{{jsxref("String.split", "split")}}Teilt ein String Objekt in ein Array von Teilstrings.
{{jsxref("String.slice", "slice")}}Gibt einen Ausschnitt des Strings als neuen String zurück.
{{jsxref("String.substring", "substring")}}, {{jsxref("String.substr", "substr")}}Gibt einen Ausschnitt des Strings zurück, der entweder durch Angabe der Start- und Endindizes oder durch Angabe des Startindex und einer Länge gebildet wird.
{{jsxref("String.match", "match")}}, {{jsxref("String.replace", "replace")}}, {{jsxref("String.search", "search")}}Verwendet Regular Expressions um Übereinstimmungen mit einem Suchmuster zu finden oder Teile des Strings zu ersetzen.
{{jsxref("String.toUpperCase", "toUpperCase")}}, {{jsxref("String.toLowerCase", "toLowerCase")}} +

Wandelt einen String in Groß- bzw Kleinschreibung um und gibt das Ergebnis als neuen String zurück.

+
{{jsxref("String.normalize", "normalize")}}Gibt die Unicode Normalization Form des Strings zurück.
{{jsxref("String.repeat", "repeat")}}Gibt einen String zurück, in dem der ursprüngliche String mehrfach aneinandergereiht wurde.
{{jsxref("String.trim", "trim")}}Entfernt Leerzeichen vom Anfang und vom Ende des Strings.
+ +

Mehrzeilige Template-Strings

+ +

Template-Strings sind String-Symbole, die eingebettete Ausdrücke erlauben. Mit diesen Ausdrücken können mehrzeilige Strings und String-Interpolation genutzt werden.

+ +

Template-Strings sind anstelle von doppelten bzw. einfachen Anführungszeichen in Back-Ticks (` `) (grave accent) eingeschlossen. Template-Strings können Platzhalter beinhalten, die durch das Dollarsymbol gefolgt von geschweiften Klammern gekennzeichnet sind (${expression}).

+ +

Mehrzeilige Strings

+ +

Alle Zeichen, die einen Zeilenumbruch einleiten und sich zwischen Back-Ticks befinden, werden als Teil des Template Strings verwendet. Bei normalen Strings muss die folgende Syntax genutzt werden, um Strings mit Zeilenumbrücken über mehrere Codezeilen zu definieren:

+ +
console.log('string text line 1\n\
+string text line 2');
+// "string text line 1
+// string text line 2"
+ +

Um dasselbe Ergebnis mit Template-Strings zu erreichen, kann die folgende Schreibweise genutzt werden:

+ +
console.log(`string text line 1
+string text line 2`);
+// "string text line 1
+// string text line 2"
+ +

Erweiterung von Ausdrücken

+ +

Um Ausdrücke in normale Strings einzufügen, müsste die folgende Syntax genutzt werden:

+ +
var a = 5;
+var b = 10;
+console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');
+// "Fifteen is 15 and
+// not 20."
+ +

Mit Template-Strings können nun die syntaktischen Vorteile genutzt werden um solche Ersetzungen leserlicher zu machen:

+ +
var a = 5;
+var b = 10;
+console.log(`Fifteen is ${a + b} and\nnot ${2 * a + b}.`);
+// "Fifteen is 15 and
+// not 20."
+ +

Mehr Informationen sind unter Template-Strings in der JavaScript-Referenz nachzulesen. 

+ +

Internationalization

+ +

Das {{jsxref("Intl")}} Objekt ist der Namespace für das ECMAScript Internationalization API, welches sprachabhängige String-Vergleiche, Zahlen-, Datums- und Uhrzeitformate bereitstellt. Die Konstruktoren für {{jsxref("Collator")}}, {{jsxref("NumberFormat")}} und {{jsxref("DateTimeFormat")}} Objekte sind Eigenschaften des Intl Objekts.

+ +

Datums- und Uhrzeitformatierung

+ +

Das {{jsxref("DateTimeFormat")}} Objekt hilft bei der Datums- oder Uhrzeitformatierung. Im folgenden Beispiel wird ein Datum für amerikanisches Englisch formatiert. (Das Ergebnis variiert je nach eingestellter Zeitzone.)

+ +
var msPerDay = 24 * 60 * 60 * 1000;
+
+// July 17, 2014 00:00:00 UTC.
+var july172014 = new Date(msPerDay * (44 * 365 + 11 + 197));
+
+var options = { year: '2-digit', month: '2-digit', day: '2-digit',
+                hour: '2-digit', minute: '2-digit', timeZoneName: 'short' };
+var americanDateTime = new Intl.DateTimeFormat('en-US', options).format;
+
+console.log(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT
+
+ +

Zahlenformatierung

+ +

Das {{jsxref("NumberFormat")}} Objekt hilft bei der Formatierung von Zahlen, wie z.B. Währungen.

+ +
var gasPrice = new Intl.NumberFormat('en-US',
+                        { style: 'currency', currency: 'USD',
+                          minimumFractionDigits: 3 });
+
+console.log(gasPrice.format(5.259)); // $5.259
+
+var hanDecimalRMBInChina = new Intl.NumberFormat('zh-CN-u-nu-hanidec',
+                        { style: 'currency', currency: 'CNY' });
+
+console.log(hanDecimalRMBInChina.format(1314.25)); // ¥ 一,三一四.二五
+
+ +

Sortierung

+ +

Das {{jsxref("Collator")}} Objekt hilft beim Vergleichen und Sortieren von Strings.

+ +

Zum Beispiel gibt es im Deutschen zwei unterschiedliche Sortierreihenfolgen: Telefonbuchsortierung und Wörterbuchsortierung. Bei der Telefonbuchsortierung werden "ä", "ö" etc. so sortiert, als ob es sich um "ae", "oe" etc. handeln würde.

+ +
var names = ['Hochberg', 'Hönigswald', 'Holzman'];
+
+var germanPhonebook = new Intl.Collator('de-DE-u-co-phonebk');
+
+// as if sorting ["Hochberg", "Hoenigswald", "Holzman"]:
+console.log(names.sort(germanPhonebook.compare).join(', '));
+// logs "Hochberg, Hönigswald, Holzman"
+
+ +

Bei manchen Beugungsformen wird ein Vokal zu einem Umlaut, daher ist es sinnvoll, Wörterbücher so zu sortieren, dass Vokale und Umlaute gleich sortiert werden. Bei der Sortierung wird dann also "ä" wie "a" und "ö" wie "o" sortiert. Eine Ausnahme stellen Wörter dar, die sich nur im Umlaut unterscheiden. In solchen Fällen wird der Vokal vor dem Umlaut gereiht (z.B. schon vor schön). 

+ +
var germanDictionary = new Intl.Collator('de-DE-u-co-dict');
+
+// as if sorting ["Hochberg", "Honigswald", "Holzman"]:
+console.log(names.sort(germanDictionary.compare).join(', '));
+// logs "Hochberg, Holzman, Hönigswald"
+
+ +

Mehr Informationen über das {{jsxref("Intl")}} API können unter Introducing the JavaScript Internationalization API (in Englisch) nachgelesen werden.

+ +
{{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}
diff --git a/files/de/web/javascript/guide/textformatierung/index.html b/files/de/web/javascript/guide/textformatierung/index.html deleted file mode 100644 index 48c45c9871..0000000000 --- a/files/de/web/javascript/guide/textformatierung/index.html +++ /dev/null @@ -1,257 +0,0 @@ ---- -title: Textformatierung -slug: Web/JavaScript/Guide/Textformatierung -tags: - - Guide - - JavaScript - - 'l10n:priority' -translation_of: Web/JavaScript/Guide/Text_formatting ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}
- -

Dieses Kapitel gibt eine Einführung darüber, wie in JavaScript mit Strings (Zeichenfolgen) und Texten gearbeitet wird.

- -

Strings

- -

JavaScript's Datentyp {{Glossary("String")}} wird verwendet, um textuelle Daten zu repräsentieren. Es handelt sich um eine Reihe von Elementen, die ganzzahlige 16-Bit-Werte ohne Vorzeichen (UTF-16 Code Units) sind. Jedes Element belegt eine Position im String. Das erste Element befindet hat den Index 0, das nächste den Index 1 usw. Die Länge des Strings ist die Anzahl der Elemente, die darin enthalten sind. Strings können über String-Literale oder String-Objekte erzeugt werden.

- -

ACHTUNG: Beim Bearbeiten dieser Seite keine Zeichen mit Zeichencode größer als U+FFFF einfügen, bis MDN bug 857438 behoben wurde ( https://bugzilla.mozilla.org/show_bug.cgi?id=857438 ).

- -

String Literale

- -

Einfache Strings können mittels einfacher oder doppelter Anführungszeichen erzeugt werden:

- -
'foo'
-"bar"
- -

Anspruchsvollere Strings können mit Escape-Sequenzen erstellt werden:

- -

Hexadezimale Escape-Sequenzen

- -

Die Zahl nach \x wird als hexadecimale Zahl interpretiert.

- -
'\xA9' // "©"
-
- -

Unicode Escape-Sequenzen

- -

Unicode Escape-Sequenzen erfordern mindestens vier hexadezimale Ziffern nach \u.

- -
'\u00A9' // "©"
- -

Unicode Code Point Escapes

- -

Diese sind neu in ECMAScript 2015. Mit Unicode Code Point Maskierung können beliebige Zeichen durch Maskierungssequenzen mit hexadezimalen Zahlen erzeugt werden, sodass die Verwendung von Unicode Code Points bis zu 0x10FFFF möglich ist. Mit einfachen Unicode Maskierungssequenz ist es oft notwendig, Surrogate-Hälften als zwei getrennte Maskierungssequenzen zu schreiben, um dasselbe Ergebnis zu erhalten.

- -

Siehe auch {{jsxref("String.fromCodePoint()")}} oder {{jsxref("String.prototype.codePointAt()")}}.

- -
'\u{2F804}'
-
-// das gleiche mit einfachen Unicode Escape-Sequenzen
-'\uD87E\uDC04'
- -

String Objekte

- -

Das {{jsxref("String")}} Objekt ist ein Wrapper für den primitiven Datentyp String.

- -
var s = new String('foo'); // Erstellt ein String object
-console.log(s); // Ausgabe: {'0': 'f', '1': 'o', '2': 'o'}
-typeof s; // Gibt 'object' zurück
-
- -

Beliebige Methoden des String Objekts können als Methoden eines String-Literals aufgerufen werden – JavaScript wandelt das String-Literal automatisch in ein temporäres String Objekt um, ruft die Methode auf und verwirft das temporäre String Objekt anschließend. Außerdem kann die String.length Eigenschaft mit einem String-Literal verwendet werden.

- -

String-Literale sollten verwendet werden, außer es wird tatsächlich ein String Objekt benötigt, da String Objekte unerwartetes Verhalten aufweisen können. Beispielsweise:

- -
var s1 = '2 + 2'; // Erzeugt ein String-Literal
-var s2 = new String('2 + 2'); // Erzeugt ein String Objekt
-eval(s1); // Gibt die Zahl 4 zurück
-eval(s2); // Gibt den String "2 + 2" zurück
- -

Ein String Objekt hat eine Eigenschaft length, die die Anzahl von der UTF-16 Code Units im String angibt. Der folgende Code beispielsweise weist der Variable x den Wert 13 zu, da "Hello, World!" aus 13 Zeichen besteht. Jedes dieser Zeichen wird durch eine UTF-16 Code Unit dargestellt. Auf jede dieser Code Units kann durch eckige Klammern zugegriffen werden. Es können jedoch keine Zeichen geändert werden, da Strings unveränderbare Array-ähnliche Objekte sind:

- -
var mystring = 'Hello, World!';
-var x = mystring.length;
-mystring[0] = 'L'; // hat keinen Effekt
-mystring[0]; // gibt "H" zurück
-
- -

Zeichen mit einem Unicode-Wert größer als U+FFFF (wie z.B. manche seltene chinesiche/japanische/koreanische/vietnamesische Zeichen und einige Emoji) werden in UTF-16 als zwei Surrogate Code Units gespeichert. Ein String, der nur aus einem Zeichen, U+1F600 ("Emoji grinning face"), besteht, hätte die Länge 2. Der Zugriff auf einzelne Code Units in einem solchen String kann zu unerwünschten Effekten führen, wie z.B. die Entstehung von String mit unvollständigen Surrogate Code Units, was gegen den Unicode Standard verstößt. (Beispiele dafür sollten zu dieser Seite hinzugefügt werden, sobald MDN bug 857438 behoben wurde.) Siehe auch {{jsxref("String.fromCodePoint()")}} oder {{jsxref("String.prototype.codePointAt()")}}.

- -

Ein String Objekt verschiedenste Methoden, unter anderem auch welche, die den String in abgewandelter Form zurückgeben, wie z.B. substring und toUpperCase.

- -

Die folgende Tabelle gibt eine Zusammenfassung der Methoden von {{jsxref("String")}} Objekten.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Methoden von String

-
MethodeBeschreibung
{{jsxref("String.charAt", "charAt")}}, {{jsxref("String.charCodeAt", "charCodeAt")}}, {{jsxref("String.codePointAt", "codePointAt")}}Gibt das Zeichen oder den Zeichencode an der angegebenen Stelle im String zurück.
{{jsxref("String.indexOf", "indexOf")}}, {{jsxref("String.lastIndexOf", "lastIndexOf")}}Gibt die erste bzw. letzte Position des angegebenen Teilstrings im String zurück.
{{jsxref("String.startsWith", "startsWith")}}, {{jsxref("String.endsWith", "endsWith")}}, {{jsxref("String.includes", "includes")}}Gibt zurück, ob ein String mit dem angegebenen Teilstring beginnt, endet oder den Teilstring enthält.
{{jsxref("String.concat", "concat")}}Fügt die beiden Strings zusammen und gibt diesen neuen String zurück.
{{jsxref("String.fromCharCode", "fromCharCode")}}, {{jsxref("String.fromCodePoint", "fromCodePoint")}}Erstellt einen String aus den angegebenen Unicode Codes. Es handelt sich um eine Methode der Klasse String, nicht die einer String Instanz.
{{jsxref("String.split", "split")}}Teilt ein String Objekt in ein Array von Teilstrings.
{{jsxref("String.slice", "slice")}}Gibt einen Ausschnitt des Strings als neuen String zurück.
{{jsxref("String.substring", "substring")}}, {{jsxref("String.substr", "substr")}}Gibt einen Ausschnitt des Strings zurück, der entweder durch Angabe der Start- und Endindizes oder durch Angabe des Startindex und einer Länge gebildet wird.
{{jsxref("String.match", "match")}}, {{jsxref("String.replace", "replace")}}, {{jsxref("String.search", "search")}}Verwendet Regular Expressions um Übereinstimmungen mit einem Suchmuster zu finden oder Teile des Strings zu ersetzen.
{{jsxref("String.toUpperCase", "toUpperCase")}}, {{jsxref("String.toLowerCase", "toLowerCase")}} -

Wandelt einen String in Groß- bzw Kleinschreibung um und gibt das Ergebnis als neuen String zurück.

-
{{jsxref("String.normalize", "normalize")}}Gibt die Unicode Normalization Form des Strings zurück.
{{jsxref("String.repeat", "repeat")}}Gibt einen String zurück, in dem der ursprüngliche String mehrfach aneinandergereiht wurde.
{{jsxref("String.trim", "trim")}}Entfernt Leerzeichen vom Anfang und vom Ende des Strings.
- -

Mehrzeilige Template-Strings

- -

Template-Strings sind String-Symbole, die eingebettete Ausdrücke erlauben. Mit diesen Ausdrücken können mehrzeilige Strings und String-Interpolation genutzt werden.

- -

Template-Strings sind anstelle von doppelten bzw. einfachen Anführungszeichen in Back-Ticks (` `) (grave accent) eingeschlossen. Template-Strings können Platzhalter beinhalten, die durch das Dollarsymbol gefolgt von geschweiften Klammern gekennzeichnet sind (${expression}).

- -

Mehrzeilige Strings

- -

Alle Zeichen, die einen Zeilenumbruch einleiten und sich zwischen Back-Ticks befinden, werden als Teil des Template Strings verwendet. Bei normalen Strings muss die folgende Syntax genutzt werden, um Strings mit Zeilenumbrücken über mehrere Codezeilen zu definieren:

- -
console.log('string text line 1\n\
-string text line 2');
-// "string text line 1
-// string text line 2"
- -

Um dasselbe Ergebnis mit Template-Strings zu erreichen, kann die folgende Schreibweise genutzt werden:

- -
console.log(`string text line 1
-string text line 2`);
-// "string text line 1
-// string text line 2"
- -

Erweiterung von Ausdrücken

- -

Um Ausdrücke in normale Strings einzufügen, müsste die folgende Syntax genutzt werden:

- -
var a = 5;
-var b = 10;
-console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');
-// "Fifteen is 15 and
-// not 20."
- -

Mit Template-Strings können nun die syntaktischen Vorteile genutzt werden um solche Ersetzungen leserlicher zu machen:

- -
var a = 5;
-var b = 10;
-console.log(`Fifteen is ${a + b} and\nnot ${2 * a + b}.`);
-// "Fifteen is 15 and
-// not 20."
- -

Mehr Informationen sind unter Template-Strings in der JavaScript-Referenz nachzulesen. 

- -

Internationalization

- -

Das {{jsxref("Intl")}} Objekt ist der Namespace für das ECMAScript Internationalization API, welches sprachabhängige String-Vergleiche, Zahlen-, Datums- und Uhrzeitformate bereitstellt. Die Konstruktoren für {{jsxref("Collator")}}, {{jsxref("NumberFormat")}} und {{jsxref("DateTimeFormat")}} Objekte sind Eigenschaften des Intl Objekts.

- -

Datums- und Uhrzeitformatierung

- -

Das {{jsxref("DateTimeFormat")}} Objekt hilft bei der Datums- oder Uhrzeitformatierung. Im folgenden Beispiel wird ein Datum für amerikanisches Englisch formatiert. (Das Ergebnis variiert je nach eingestellter Zeitzone.)

- -
var msPerDay = 24 * 60 * 60 * 1000;
-
-// July 17, 2014 00:00:00 UTC.
-var july172014 = new Date(msPerDay * (44 * 365 + 11 + 197));
-
-var options = { year: '2-digit', month: '2-digit', day: '2-digit',
-                hour: '2-digit', minute: '2-digit', timeZoneName: 'short' };
-var americanDateTime = new Intl.DateTimeFormat('en-US', options).format;
-
-console.log(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT
-
- -

Zahlenformatierung

- -

Das {{jsxref("NumberFormat")}} Objekt hilft bei der Formatierung von Zahlen, wie z.B. Währungen.

- -
var gasPrice = new Intl.NumberFormat('en-US',
-                        { style: 'currency', currency: 'USD',
-                          minimumFractionDigits: 3 });
-
-console.log(gasPrice.format(5.259)); // $5.259
-
-var hanDecimalRMBInChina = new Intl.NumberFormat('zh-CN-u-nu-hanidec',
-                        { style: 'currency', currency: 'CNY' });
-
-console.log(hanDecimalRMBInChina.format(1314.25)); // ¥ 一,三一四.二五
-
- -

Sortierung

- -

Das {{jsxref("Collator")}} Objekt hilft beim Vergleichen und Sortieren von Strings.

- -

Zum Beispiel gibt es im Deutschen zwei unterschiedliche Sortierreihenfolgen: Telefonbuchsortierung und Wörterbuchsortierung. Bei der Telefonbuchsortierung werden "ä", "ö" etc. so sortiert, als ob es sich um "ae", "oe" etc. handeln würde.

- -
var names = ['Hochberg', 'Hönigswald', 'Holzman'];
-
-var germanPhonebook = new Intl.Collator('de-DE-u-co-phonebk');
-
-// as if sorting ["Hochberg", "Hoenigswald", "Holzman"]:
-console.log(names.sort(germanPhonebook.compare).join(', '));
-// logs "Hochberg, Hönigswald, Holzman"
-
- -

Bei manchen Beugungsformen wird ein Vokal zu einem Umlaut, daher ist es sinnvoll, Wörterbücher so zu sortieren, dass Vokale und Umlaute gleich sortiert werden. Bei der Sortierung wird dann also "ä" wie "a" und "ö" wie "o" sortiert. Eine Ausnahme stellen Wörter dar, die sich nur im Umlaut unterscheiden. In solchen Fällen wird der Vokal vor dem Umlaut gereiht (z.B. schon vor schön). 

- -
var germanDictionary = new Intl.Collator('de-DE-u-co-dict');
-
-// as if sorting ["Hochberg", "Honigswald", "Holzman"]:
-console.log(names.sort(germanDictionary.compare).join(', '));
-// logs "Hochberg, Holzman, Hönigswald"
-
- -

Mehr Informationen über das {{jsxref("Intl")}} API können unter Introducing the JavaScript Internationalization API (in Englisch) nachgelesen werden.

- -
{{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}
diff --git a/files/de/web/javascript/guide/working_with_objects/index.html b/files/de/web/javascript/guide/working_with_objects/index.html new file mode 100644 index 0000000000..2448621a4a --- /dev/null +++ b/files/de/web/javascript/guide/working_with_objects/index.html @@ -0,0 +1,506 @@ +--- +title: Mit Objekten arbeiten +slug: Web/JavaScript/Guide/Mit_Objekten_arbeiten +tags: + - Beginner + - Comparing object + - Constructor + - Document + - Guide + - JavaScript + - Object + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Working_with_Objects +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Feinheiten_des_Objektmodells")}}
+ +

JavaScript ist nach einem einfachen objekt-basierten Muster entworfen. Ein Objekt ist eine Sammlung von Eigenschaften und eine Eigenschaft ist eine Verbindung von einem Namen und einem Wert. Der Wert einer Eigenschaft kann eine Funktion sein. In diesem Fall wird die Eigenschaft Methode genannt. Zusätzlich zu Objekten, die vom Browser vordefiniert sind, können auch eigene Objekte definiert werden. Dieses Kapitel beschreibt, wie Objekte, Eigenschaften, Funktionen und Methoden benutzt und eigene Objekte erzeugt werden können.

+ +

Objekte Übersicht

+ +

Objekte in JavaScript, wie in vielen anderen Programmiersprachen, können mit Objekten aus dem realen Leben verglichen werden. Das Konzept der Objekte in JavaScript kann mit greifbaren Objekten aus der realen Welt verstanden werden.

+ +

In JavaScript ist ein Objekt eine für sich stehende Einheit mit Eigenschaften und Typ. Vergleichbar mit einer Tasse zum Beispiel. Eine Tasse ist ein Objekt mit Eigenschaften. Eine Tasse hat eine Farbe, ein Design, ein Gewicht, ein Material, aus dem sie erstellt wurde, usw. Ebenso können JavaScript Objekte Eigenschaften besitzen, die Ihre Besonderheiten definieren.

+ +

Objekte und Eigenschaften

+ +

Ein JavaScript Objekt besitzt mit ihm verbundene Eigenschaften. Eine Eigenschaft eines Objekts kann als Variable erklärt werden, die dem Objekt angeheftet ist. Objekteigenschaften sind grundsätzlich das Gleiche wie übliche Variablen ausser der Verknüpfung mit Objekten. Die Eigenschaften eines Objekts definieren seine Charakteristik. Auf die Eigenschaften eines Objekt kann mit einer einfachen Punkt-Notation zugegriffen werden:

+ +
objectName.propertyName
+
+ +

Wie bei allen JavaScript-Variablen sind Objektname (eine normale Variable) und Attribute groß-, und kleinschreibungsabhängig. Ein Attribut wird definiert, indem es einen Wert zugewiesen bekommt. Zum Beispiel: Ein Objekt namens myCar mit den Attributen make, model, und year:

+ +
var myCar = new Object();
+myCar.make = "Ford";
+myCar.model = "Mustang";
+myCar.year = 1969;
+
+ +

Nicht initialisierte Eigenschaften eines Objektes haben den Wert {{jsxref("undefined")}} (nicht {{jsxref("null")}}).

+ +
myCar.color; // undefined
+ +

Eigenschaften von JavaScript-Objekten können auch mit der Klammernotation (für weitere Informationen siehe property accessors). Objekte werden manchmal assoziative Arrays genannt da jede Eigenschaft mit einer Zeichenkette assoziiert ist mit der man auf die Eigenschaft zugreifen kann. Zum Beispiel kann man auf die Eigenschaften des Objekts myCar folgendermassen zugreifen:

+ +
myCar["make"] = "Ford";
+myCar["model"] = "Mustang";
+myCar["year"] = 1969;
+
+ +

Der Name einer Objekteigenschaft kann ein valider JavaScript String sein. Dies kann auch alles sein, was in einen String convertiert werden kann, inklusive eines leeren Strings. Immer, wenn der Name einer Eigenschaft kein valider JavaScript Bezeichner ist (zum Beispiel ein Name mit einem Leerzeichen oder einem minus oder ein Name der mit einer Ziffer beginnt), kann dieses nur über die Klammernotation erreicht werden. Diese Notation ist zusätzlich sehr hilfreich, wenn Namen von Eigenschaften dynamisch ermittelt werden (Wenn die Namen nicht bis zur Laufzeit ermittelt werden können). Im folgenden ein Beispiel:

+ +
// four variables are created and assigned in a single go,
+// separated by commas
+var myObj = new Object(),
+    str = 'myString',
+    rand = Math.random(),
+    obj = new Object();
+
+myObj.type              = 'Dot syntax';
+myObj['date created']   = 'String with space';
+myObj[str]              = 'String value';
+myObj[rand]             = 'Random Number';
+myObj[obj]              = 'Object';
+myObj['']               = 'Even an empty string';
+
+console.log(myObj);
+
+ +

Zu bemerken ist, dass alle Schlüssel in der Klammernotation zum Typ Strings konvertiert werden, weil in JavaScript nur Strings als Schlüssel bei Objekte erlaubt sind. Zum Beispiel wird im orberen Beispiel obj konvertiert wenn es in myObj benutzt wird. JavaScript ruft die obj.toString() Methode auf und benutzt den resultierenden String als neuen Schlüssel.

+ +

Man kann eine Eigenschaft auch erreichen, indem eine Variable vom Typ String benutzt wird:

+ +
var propertyName = 'make';
+myCar[propertyName] = 'Ford';
+
+propertyName = 'model';
+myCar[propertyName] = 'Mustang';
+
+ +

Man kann die Klammernotation mit for...in nutzen, um über alle enumerable (aufzählbaren) Eigenschaften eines Objektes zu iterieren. Um dieses zu zeigen wie das funktioniert, zeigt die folgende Funktion die Eigenschaften eines Objektes, wenn eine Objekt und der Name des Objektes der Funktion als Parameter übergeben werden:

+ +
function showProps(obj, objName) {
+  var result = '';
+  for (var i in obj) {
+    // obj.hasOwnProperty() wird benutzt um Eigenschaften aus der Prototypen-Kette herauszufiltern
+    if (obj.hasOwnProperty(i)) {
+      result += objName + '.' + i + ' = ' + obj[i] + '\n';
+    }
+  }
+  return result;
+}
+
+ +

So gibt der Aufruf showProps(myCar, "myCar") folgenden Rückgabewert zurück:

+ +
myCar.make = Ford
+myCar.model = Mustang
+myCar.year = 1969
+ +

Enumerate the properties of an object

+ +

Starting with ECMAScript 5, there are three native ways to list/traverse object properties:

+ + + +

Before ECMAScript 5, there was no native way to list all properties of an object. However, this can be achieved with the following function:

+ +
function listAllProperties(o) {
+	var objectToInspect;
+	var result = [];
+
+	for(objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect)) {
+      result = result.concat(Object.getOwnPropertyNames(objectToInspect));
+	}
+
+	return result;
+}
+
+ +

This can be useful to reveal "hidden" properties (properties in the prototype chain which are not accessible through the object, because another property has the same name earlier in the prototype chain). Listing accessible properties only can easily be done by removing duplicates in the array.

+ +

Creating new objects

+ +

JavaScript has a number of predefined objects. In addition, you can create your own objects. You can create an object using an object initializer. Alternatively, you can first create a constructor function and then instantiate an object invoking that function in conjunction with the new operator.

+ +

Using object initializers

+ +

In addition to creating objects using a constructor function, you can create objects using an object initializer. Using object initializers is sometimes referred to as creating objects with literal notation. "Object initializer" is consistent with the terminology used by C++.

+ +

The syntax for an object using an object initializer is:

+ +
var obj = { property_1:   value_1,   // property_# may be an identifier...
+            2:            value_2,   // or a number...
+            // ...,
+            'property n': value_n }; // or a string
+
+ +

where obj is the name of the new object, each property_i is an identifier (either a name, a number, or a string literal), and each value_i is an expression whose value is assigned to the property_i. The obj and assignment is optional; if you do not need to refer to this object elsewhere, you do not need to assign it to a variable. (Note that you may need to wrap the object literal in parentheses if the object appears where a statement is expected, so as not to have the literal be confused with a block statement.)

+ +

Object initializers are expressions, and each object initializer results in a new object being created whenever the statement in which it appears is executed. Identical object initializers create distinct objects that will not compare to each other as equal. Objects are created as if a call to new Object() were made; that is, objects made from object literal expressions are instances of Object.

+ +

The following statement creates an object and assigns it to the variable x if and only if the expression cond is true:

+ +
if (cond) var x = {greeting: 'hi there'};
+
+ +

The following example creates myHonda with three properties. Note that the engine property is also an object with its own properties.

+ +
var myHonda = {color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}};
+
+ +

You can also use object initializers to create arrays. See array literals.

+ +

Using a constructor function

+ +

Alternatively, you can create an object with these two steps:

+ +
    +
  1. Define the object type by writing a constructor function. There is a strong convention, with good reason, to use a capital initial letter.
  2. +
  3. Create an instance of the object with new.
  4. +
+ +

To define an object type, create a function for the object type that specifies its name, properties, and methods. For example, suppose you want to create an object type for cars. You want this type of object to be called Car, and you want it to have properties for make, model, and year. To do this, you would write the following function:

+ +
function Car(make, model, year) {
+  this.make = make;
+  this.model = model;
+  this.year = year;
+}
+
+ +

Notice the use of this to assign values to the object's properties based on the values passed to the function.

+ +

Now you can create an object called mycar as follows:

+ +
var mycar = new Car('Eagle', 'Talon TSi', 1993);
+
+ +

This statement creates mycar and assigns it the specified values for its properties. Then the value of mycar.make is the string "Eagle", mycar.year is the integer 1993, and so on.

+ +

You can create any number of Car objects by calls to new. For example,

+ +
var kenscar = new Car('Nissan', '300ZX', 1992);
+var vpgscar = new Car('Mazda', 'Miata', 1990);
+
+ +

An object can have a property that is itself another object. For example, suppose you define an object called person as follows:

+ +
function Person(name, age, sex) {
+  this.name = name;
+  this.age = age;
+  this.sex = sex;
+}
+
+ +

and then instantiate two new person objects as follows:

+ +
var rand = new Person('Rand McKinnon', 33, 'M');
+var ken = new Person('Ken Jones', 39, 'M');
+
+ +

Then, you can rewrite the definition of Car to include an owner property that takes a person object, as follows:

+ +
function Car(make, model, year, owner) {
+  this.make = make;
+  this.model = model;
+  this.year = year;
+  this.owner = owner;
+}
+
+ +

To instantiate the new objects, you then use the following:

+ +
var car1 = new Car('Eagle', 'Talon TSi', 1993, rand);
+var car2 = new Car('Nissan', '300ZX', 1992, ken);
+
+ +

Notice that instead of passing a literal string or integer value when creating the new objects, the above statements pass the objects rand and ken as the arguments for the owners. Then if you want to find out the name of the owner of car2, you can access the following property:

+ +
car2.owner.name
+
+ +

Note that you can always add a property to a previously defined object. For example, the statement

+ +
car1.color = 'black';
+
+ +

adds a property color to car1, and assigns it a value of "black." However, this does not affect any other objects. To add the new property to all objects of the same type, you have to add the property to the definition of the Car object type.

+ +

Using the Object.create method

+ +

Objects can also be created using the {{jsxref("Object.create()")}} method. This method can be very useful, because it allows you to choose the prototype object for the object you want to create, without having to define a constructor function.

+ +
// Animal properties and method encapsulation
+var Animal = {
+  type: 'Invertebrates', // Default value of properties
+  displayType: function() {  // Method which will display type of Animal
+    console.log(this.type);
+  }
+};
+
+// Create new animal type called animal1
+var animal1 = Object.create(Animal);
+animal1.displayType(); // Output:Invertebrates
+
+// Create new animal type called Fishes
+var fish = Object.create(Animal);
+fish.type = 'Fishes';
+fish.displayType(); // Output:Fishes
+ +

Inheritance

+ +

All objects in JavaScript inherit from at least one other object. The object being inherited from is known as the prototype, and the inherited properties can be found in the prototype object of the constructor. See Inheritance and the prototype chain for more information.

+ +

Indexing object properties

+ +

You can refer to a property of an object either by its property name or by its ordinal index. If you initially define a property by its name, you must always refer to it by its name, and if you initially define a property by an index, you must always refer to it by its index.

+ +

This restriction applies when you create an object and its properties with a constructor function (as we did previously with the Car object type) and when you define individual properties explicitly (for example, myCar.color = "red"). If you initially define an object property with an index, such as myCar[5] = "25 mpg", you subsequently refer to the property only as myCar[5].

+ +

The exception to this rule is objects reflected from HTML, such as the forms array. You can always refer to objects in these arrays by either their ordinal number (based on where they appear in the document) or their name (if defined). For example, if the second <FORM> tag in a document has a NAME attribute of "myForm", you can refer to the form as document.forms[1] or document.forms["myForm"] or document.forms.myForm.

+ +

Defining properties for an object type

+ +

You can add a property to a previously defined object type by using the prototype property. This defines a property that is shared by all objects of the specified type, rather than by just one instance of the object. The following code adds a color property to all objects of type Car, and then assigns a value to the color property of the object car1.

+ +
Car.prototype.color = null;
+car1.color = 'black';
+
+ +

See the prototype property of the Function object in the JavaScript reference for more information.

+ +

Defining methods

+ +

A method is a function associated with an object, or, simply put, a method is a property of an object that is a function. Methods are defined the way normal functions are defined, except that they have to be assigned as the property of an object. See also method definitions for more details. An example is:

+ +
objectName.methodname = functionName;
+
+var myObj = {
+  myMethod: function(params) {
+    // ...do something
+  }
+
+  // OR THIS WORKS TOO
+
+  myOtherMethod(params) {
+    // ...do something else
+  }
+};
+
+ +

where objectName is an existing object, methodname is the name you are assigning to the method, and functionName is the name of the function.

+ +

You can then call the method in the context of the object as follows:

+ +
object.methodname(params);
+
+ +

You can define methods for an object type by including a method definition in the object constructor function. You could define a function that would format and display the properties of the previously-defined Car objects; for example,

+ +
function displayCar() {
+  var result = 'A Beautiful ' + this.year + ' ' + this.make
+    + ' ' + this.model;
+  pretty_print(result);
+}
+
+ +

where pretty_print is a function to display a horizontal rule and a string. Notice the use of this to refer to the object to which the method belongs.

+ +

You can make this function a method of Car by adding the statement

+ +
this.displayCar = displayCar;
+
+ +

to the object definition. So, the full definition of Car would now look like

+ +
function Car(make, model, year, owner) {
+  this.make = make;
+  this.model = model;
+  this.year = year;
+  this.owner = owner;
+  this.displayCar = displayCar;
+}
+
+ +

Then you can call the displayCar method for each of the objects as follows:

+ +
car1.displayCar();
+car2.displayCar();
+
+ +

Using this for object references

+ +

JavaScript has a special keyword, this, that you can use within a method to refer to the current object. For example, suppose you have a function called validate that validates an object's value property, given the object and the high and low values:

+ +
function validate(obj, lowval, hival) {
+  if ((obj.value < lowval) || (obj.value > hival)) {
+    alert('Invalid Value!');
+  }
+}
+
+ +

Then, you could call validate in each form element's onchange event handler, using this to pass it the element, as in the following example:

+ +
<input type="text" name="age" size="3"
+  onChange="validate(this, 18, 99)">
+
+ +

In general, this refers to the calling object in a method.

+ +

When combined with the form property, this can refer to the current object's parent form. In the following example, the form myForm contains a Text object and a button. When the user clicks the button, the value of the Text object is set to the form's name. The button's onclick event handler uses this.form to refer to the parent form, myForm.

+ +
<form name="myForm">
+<p><label>Form name:<input type="text" name="text1" value="Beluga"></label>
+<p><input name="button1" type="button" value="Show Form Name"
+     onclick="this.form.text1.value = this.form.name">
+</p>
+</form>
+ +

Defining getters and setters

+ +

A getter is a method that gets the value of a specific property. A setter is a method that sets the value of a specific property. You can define getters and setters on any predefined core object or user-defined object that supports the addition of new properties. The syntax for defining getters and setters uses the object literal syntax.

+ +

The following illustrates how getters and setters could work for a user-defined object o.

+ +
var o = {
+  a: 7,
+  get b() {
+    return this.a + 1;
+  },
+  set c(x) {
+    this.a = x / 2;
+  }
+};
+
+console.log(o.a); // 7
+console.log(o.b); // 8
+o.c = 50;
+console.log(o.a); // 25
+
+ +

The o object's properties are:

+ + + +

Please note that function names of getters and setters defined in an object literal using "[gs]et property()" (as opposed to __define[GS]etter__ ) are not the names of the getters themselves, even though the [gs]et propertyName(){ } syntax may mislead you to think otherwise. To name a function in a getter or setter using the "[gs]et property()" syntax, define an explicitly named function programmatically using Object.defineProperty (or the Object.prototype.__defineGetter__ legacy fallback).

+ +

The following code illustrates how getters and setters can extend the {{jsxref("Date")}} prototype to add a year property to all instances of the predefined Date class. It uses the Date class's existing getFullYear and setFullYear methods to support the year property's getter and setter.

+ +

These statements define a getter and setter for the year property:

+ +
var d = Date.prototype;
+Object.defineProperty(d, 'year', {
+  get: function() { return this.getFullYear(); },
+  set: function(y) { this.setFullYear(y); }
+});
+
+ +

These statements use the getter and setter in a Date object:

+ +
var now = new Date();
+console.log(now.year); // 2000
+now.year = 2001; // 987617605170
+console.log(now);
+// Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
+
+ +

In principle, getters and setters can be either

+ + + +

When defining getters and setters using object initializers all you need to do is to prefix a getter method with get and a setter method with set. Of course, the getter method must not expect a parameter, while the setter method expects exactly one parameter (the new value to set). For instance:

+ +
var o = {
+  a: 7,
+  get b() { return this.a + 1; },
+  set c(x) { this.a = x / 2; }
+};
+
+ +

Getters and setters can also be added to an object at any time after creation using the Object.defineProperties method. This method's first parameter is the object on which you want to define the getter or setter. The second parameter is an object whose property names are the getter or setter names, and whose property values are objects for defining the getter or setter functions. Here's an example that defines the same getter and setter used in the previous example:

+ +
var o = { a: 0 };
+
+Object.defineProperties(o, {
+    'b': { get: function() { return this.a + 1; } },
+    'c': { set: function(x) { this.a = x / 2; } }
+});
+
+o.c = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
+console.log(o.b); // Runs the getter, which yields a + 1 or 6
+
+ +

Which of the two forms to choose depends on your programming style and task at hand. If you already go for the object initializer when defining a prototype you will probably most of the time choose the first form. This form is more compact and natural. However, if you need to add getters and setters later — because you did not write the prototype or particular object — then the second form is the only possible form. The second form probably best represents the dynamic nature of JavaScript — but it can make the code hard to read and understand.

+ +

Deleting properties

+ +

You can remove a non-inherited property by using the delete operator. The following code shows how to remove a property.

+ +
// Creates a new object, myobj, with two properties, a and b.
+var myobj = new Object;
+myobj.a = 5;
+myobj.b = 12;
+
+// Removes the a property, leaving myobj with only the b property.
+delete myobj.a;
+console.log ('a' in myobj); // yields "false"
+
+ +

You can also use delete to delete a global variable if the var keyword was not used to declare the variable:

+ +
g = 17;
+delete g;
+
+ +

Comparing Objects

+ +

In JavaScript objects are a reference type. Two distinct objects are never equal, even if they have the same properties. Only comparing the same object reference with itself yields true.

+ +
// Two variables, two distinct objects with the same properties
+var fruit = {name: 'apple'};
+var fruitbear = {name: 'apple'};
+
+fruit == fruitbear; // return false
+fruit === fruitbear; // return false
+ +
// Two variables, a single object
+var fruit = {name: 'apple'};
+var fruitbear = fruit;  // assign fruit object reference to fruitbear
+
+// here fruit and fruitbear are pointing to same object
+fruit == fruitbear; // return true
+fruit === fruitbear; // return true
+
+ +
fruit.name = 'grape';
+console.log(fruitbear);    // yields { name: "grape" } instead of { name: "apple" }
+
+ +

For more information about comparison operators, see Comparison operators.

+ +

See also

+ + + +

{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Feinheiten_des_Objektmodells")}}

-- cgit v1.2.3-54-g00ecf