Neu in JavaScript 1.7

  • Adressname der Version: JavaScript/Neu_in_JavaScript/1.7
  • Titel der Version: Neu in JavaScript 1.7
  • ID der Version: 449653
  • Erstellt:
  • Autor: eminor
  • Aktuelle Version? Nein
  • Kommentar

Inhalt der Version

{{ Fx_minversion_header(2) }}

JavaScript 1.7 ist ein Update für die Sprache, womit mehrere neue Features wie Generatoren, Iteratoren, Array-Comprehensions, let-Ausdrücke, und destructing assignments hinzugefügt wurden. Es enthält außerdem alle Features von JavaScript 1.6.

Die Unterstützung von JavaScript 1.7 beginnt mit Firefox 2.

Die in diesem Artikel enthaltenen Code-Beispiele können in der JavaScript-Shell getestet werden. Lesen Sie Introduction to the JavaScript shell, um mehr über die Benutzung der Shell zu lernen.

Verwendung von JavaScript 1.7

Möchte man einige der neuen Features von JavaScript 1.7 verwenden, sollte man dies angeben. Bei HTML oder XUL z. B. wie folgt:

<script type="application/javascript;version=1.7"></script>

Bei der Verwendung der JavaScript-Shell gibt man die Version über den Parameter -version 170 auf der Kommandozeile an oder benutzt die Funktion version():

version(170);

Neue Features, welche die Benutzung von neuen Schüsselwörtern wie yield und let einschließen, setzen die Versionsangabe voraus, da bei existierendem Code diese Schlüsselwörter eventuell bereits als Bezeichner für Variablen oder Funktionen verwendet werden. Die Features, welche keine neuen Schlüsselwörter einführen (destructing assignments und Array-Comprehensions) können ohne die Versionsangabe verwendet werden.

Generatoren und Iteratoren (siehe Iteratoren und Generatoren)

Bei der Entwicklung von Code, in dem iterative Algorithmen eingesetzt werden (wie z. B. Iterieren über Listen, XML-Nodes, Datenbank-Ausgaben; oder wiederholtes Verarbeiten desselben Datensatzes) gibt es oft Status-Variablen, deren Werte während des Verbeitungsprozesses verändert werden müssen. Tradiotionell müssen die vorübergehenden Werte dann über eine Callback-Funktion bezogen werden.

Generatoren

Hier ein Beispiel mit einem iterativer Algorithmus für die Berechnung von Fibonacci-Zahlen:

function do_callback(num) {
  console.log(num);
}

function fib() {
  var i = 0, j = 1, n = 0;
  while (n < 10) {
    do_callback(i);
    var t = i;
    i = j;
    j += t;
    n++;
  }
}

fib();

Bei diesem Code kommt eine Callback-Routine zum Einsatz, um bei jedem iterativen Schritt des Algorithmus bestimmte Operationen durchzuführen. In diesem Fall wird jede Fibonacci-Zahl einfach auf der Konsole ausgegeben.

Generatoren und Iteratoren arbeiten zusammen, um dies besser umzusetzen. Im Anschluss ein Beispiel zur Berechnung von Fibonacci-Zahlen unter Einsatz eines Generators:

function fib() {
  var i = 0, j = 1;
  while (true) {
    yield i;
    var t = i;
    i = j;
    j += t;
  }
}

var g = fib();
for (var i = 0; i < 10; i++) {
  console.log(g.next());
}

Bei der Funktion, welche das Schlüsselwort yield enthält, handelt es sich um einen Generator. Beim Aufruf dieser Funktion werden ihre formalen Parameter an aktuelle Argumente gebunden, aber der Code nicht ausgeführt, sondern stattdessen ein Generator-Iterator zurückgegeben. Bei jedem Aufruf der next()-Methode des Generator-Iterators wird dann ein weiterer Iterationsschritt ausgeführt. Der Rückgabewert jedes Durchlaufs ist der nach yield stehende Wert. Man kann sich yield ungefähr wie eine spezielles return für Generator-Iterator-Objekte vorstellen, welches die Begrenzung für jeden Iterationsschritt festlegt. Bei jedem Aufruf von next() wird die Ausführung dann bei der Anweisung nach yield fortgesetzt.

Ein Generator-Iterator wird durchlaufen, indem die Methode next() wiederholt aufgerufen wird, solange bis schließlich das gewünscht Ergebnis erreicht bzw. die Bedingung erfüllt ist. Bei dem Beispiel mit den Fibonacci-Zahlen ruft man also wiederholt g.next() auf, bis man die gewünschte Anzahl von Fibonacci-Zahlen erzeugt hat.

Fortsetzen eines Generators an einem bestimmten Punkt

Sobald ein Generator einmal durch den Aufruf der next()-Methode gestartet wurde, kann der Methode send() ein beliebiger Wert an den Generator übergeben werden. Dieser Wert wird dann so interpriert, als wäre es der Wert des letzten yield. Der Generator gibt dann den Operanden des darauf folgenden yield zurück.

Ein Generator lässt sich nicht an einem bestimtmen Punkt starten, sondern nur über die Methode next(). Erst nach dem next()-Aufruf kann über send() ein Wert gesetzt werden.

Achtung: Der Aufruf von send(undefined) ist äquivalent zum Aufruf von next(). Jeder Start eines neuen Generator über send() mit einem anderen Wert als undefined resultiert jedoch in einem TypeError-Ausnahmefehler.

Ausnahmen bei Generatoren

Man kann einen Generator dazu bringen, eine Ausnahme auszuwerfen, indem man seine throw()-Methode aufruft und einen Wert übergibt, der ausgeworfen werden soll. Diese Ausnahme wird unter Einbeziehung des Kontext der aktuellen Unterbrechung ausgeworfen, so als wäre das yield des aktuellen Durchlaufs eine Anweisung throw Wert.

Trifft die Ausführung während der Verarbeitung der ausgeworfenen Ausnahme auf kein yield, so verbreitet sich die Ausnahme bis nach oben durch den Aufruf bis zu next() und nachfolgende Aufrufe von next() lösen eine StopIteration-Ausnahme aus.

Schließen eines Generators

Generatoren besitzen eine Methode close(), welche den Generator zwingt, sich selbst zu schließen. Die Effekte einer solchen Schließung sind folgende:

  1. Jede finally-Klausel, die in der Generator-Funktion aktiv ist, wird ausgeführt.
  2. Wird durch eine finally-Klausel eine andere Ausnahme als StopIteration ausgeworfen, wird diese an die Funktion weitergeleitet, die close() aufgerufen hat.
  3. Der Generator terminiert.

Generator-Beispiel

Dieser Code arbeitet mit einem Generator, der alle 100 Schleifendurchläufe etwas "abwirft" (yield = abwerfen):

var gen = generator();

function driveGenerator() {
  if (gen.next()) {
    window.setTimeout(driveGenerator, 0);	
  } else {
    gen.close();	
  }
}

function generator() {
  while (i < something) {
    /** stuff **/

    ++i;
    /** 100 loops per yield **/
    if ((i % 100) == 0) {
      yield true;
    } 
  }
  yield false;
}

Iteratoren

Ein Iterator ist ein spezielles Objekt, das es erlaubt über Daten zu iterieren.

Bei der normalen Benutzung sind Iterator-Objekte "unsichtbar"; man braucht sie nicht explizit abzusprechen, sondern setzt stattdessen for...in und for each...in Anweisungen ein, um über Schlüssel und/oder Werte von Objekten zu iterieren.

var objectWithIterator = getObjectSomehow();

for (var i in objectWithIterator)
{
  console.log(objectWithIterator[i]);
}

Für die Implementierung eines eigenen Iterator-Objekts oder zur direkten Veränderung von Iteratoren sollte man über die next()-Methode, die StopIteration-Ausnahme und die __iterator__-Methode informiert sein.

Ein Iterator für ein Objekt kann man mit dem Aufruf von Iterator(objectname); erzeugen. Der Iterator kann über die Methode __iterator__ gefunden werden; ist diese Methode nicht vorhanden, wird ein Default-Iterator erstellt. Der Default-Iterator wirft über yield die Eigenschaften des Objekts ab. Möchte man stattdessen einen selbstdefinierten Iterator einsetzen, überschreibt man die Methode __iterator__, damit diese eine Instanz des selbstbefinierten Iterators zurückgibt. Um den Iterator eines Objekts über ein Skript abzufragen, sollte man auf Iterator(obj) statt direkt auf __iterator__ zurückgreifen. Ersteres funktioniert für Arrays, letzteres nicht.

Nach Erzeugung des Iterators kann man einfach über die Methode next() das nächste Element abfragen. Sind keine Daten mehr vorhanden, wird eine StopIteration-Ausnahme ausgeworfen.

Hier ein einfaches Beispiel für die direkte Manipulation eines Iterators:

var obj = {name:"Jack Bauer", username:"JackB", id:12345, agency:"CTU",
          region:"Los Angeles"};

var it = Iterator(obj);

try {
  while (true) {
    print(it.next() + "\n");
  }
} catch (err if err instanceof StopIteration) {
  print("End of record.\n");
} catch (err) {
  print("Unknown error: " + err.description + "\n");
}

Die Ausgabe dieses Codes ist wie folgt:

name,Jack Bauer
username,JackB
id,12345
agency,CTU
region,Los Angeles
End of record.

Optional kann man bei der Erstellung eines Iterators einen booleschen Wert als zweiten Parameter angeben, womit festgelegt wird, ob nur der jeweilge Schlüssel beim Aufruf der next()-Methode zurückgegeben werden soll. Der Paramater wird an benutzerdefinierte __iterator__-Funktionen als einziges Argument übergeben. Würde man beim Beispiel oben die Anweisung var it = Iterator(obj); in var it = Iterator(obj, true); ändern, würde man folgende Ausgabe erhalten:

name
username
id
agency
region
End of record.

In beiden Fällen kann die Reihenfolge der Datenausgabe je nach Implemetierung variieren. Es gibt keine Garantie für eine bestimmte Anordung der ausgegebenen Daten.

Iteroren sind nützlich, um die Daten in einem Objekt abzufragen. Solche Objekte, die Daten enthalten, von denen man zunächst nicht weiß, eingeschlossen. Das kann hilfreich sein, wenn man Daten hinterlegen muss, die von einer Applikation nicht erwartet werden.

Array-Comprehensions (siehe Array comprehensions)

Array-Comprehensions nutzen Generatoren für die effiziente Initialisierung von Arrays. Zum Beispiel:

function range(begin, end) {
  for (let i = begin; i < end; ++i) {
    yield i;
  }
}

range() ist ein Generator, der alle Werte zwischen begin und end zurückgibt. Nach der Definition kann der Generator wie folgt benutzt werden:

var ten_squares = [i * i for each (i in range(0, 10))];

Damit wird ein Array ten_squares vorinitialisiert, welches die Qudratzahlen der Werte von 0 bis 9 enthält.

Bei der Initialisierung können beliebige Bedingungen angegeben werden. Mit folgendem Code wird z. B. ein Array initialisiert, welches die geraden Zahlen zwischen 0 und 20 enthält:

var evens = [i for each (i in range(0, 21)) if (i % 2 == 0)];

Bei Versionen vor JavaScript 1.7 würde man dies ungefähr so umsetzen:

var evens = [];
for (var i=0; i <= 20; i++) {
  if (i % 2 == 0)
    evens.push(i);
}

Die Array-Comprehension ist nicht nur kompakter, sondern auch lesbarer, sobald man das Konzept einmal verstanden hat.

Regeln für die Sichtbarkeit (Scope)

Array-Comprehensions sind von einen impliziten Block abgegrenzt, der alles, was zwischen den eckige Klammern steht, enthält; inklusive impliziter let-Deklarationen.

Block-Begrenzungen mit let (siehe let Statement)

There are several ways in which let can be used to manage block scope of data and functions:

let statement

The let statement provides local scoping for variables. It works by binding zero or more variables in the lexical scope of a single block of code; otherwise, it is exactly the same as a block statement. Note in particular that the scope of a variable declared inside a let statement using var is still the same as if it had been declared outside the let statement; such variables still have function scoping.

For example:

var x = 5;
var y = 0;

let (x = x+10, y = 12) {
  console.log(x+y); // 27
}

console.log(x + y); // 5

The rules for the code block are the same as for any other code block in JavaScript. It may have its own local variables established using the let declarations.

Note: When using the let statement syntax, the parentheses following let are required. Failure to include them will result in a syntax error.

Scoping rules

The scope of variables defined using let is the let block itself, as well as any inner blocks contained inside it, unless those blocks define variables by the same names.

let expressions

You can use let to establish variables that are scoped only to a single expression:

var x = 5;
var y = 0;
console.log(let(x = x + 10, y = 12) x + y);
console.log(x + y);

The resulting output is:

27
5

In this case, the binding of the values of x and y to x+10 and 12 are scoped solely to the expression x + y + "<br>\n".

Scoping rules

Given a let expression:

let (decls) expr

There is an implicit block created around expr.

let definitions

The let keyword can also be used to define variables inside a block.

Note: If you have more interesting examples of ways to use let definitions, please consider adding them here.
if (x > y) {
  let gamma = 12.7 + y;
  i = gamma * x;
}

You can use let definitions to alias pseudo-namespaced code in extensions. (See Security best practices in extensions.)

let Cc = Components.classes, Ci = Components.interfaces;

let statements, expressions and definitions sometimes make the code cleaner when inner functions are used.

var list = document.getElementById("list");

for (var i = 1; i <= 5; i++) {
  var item = document.createElement("LI");
  item.appendChild(document.createTextNode("Item " + i));

  let j = i;
  item.onclick = function (ev) {
    alert("Item " + j + " is clicked.");
  };
  list.appendChild(item);
}

The example above works as intended because the five instances of the (anonymous) inner function refer to five different instances of variable j. Note that it does not work as intended if you replace let by var or if you remove the variable j and simply use the variable i in the inner function.

Scoping rules

Variables declared by let have as their scope the block in which they are defined, as well as in any sub-blocks in which they aren't redefined. In this way, let works very much like var. The main difference is that the scope of a var variable is the entire enclosing function:

function varTest() {
  var x = 31;
  if (true) {
    var x = 71;  // same variable!
    alert(x);  // 71
  }
  alert(x);  // 71
}

function letTest() {
  let x = 31;
  if (true) {
    let x = 71;  // different variable
    alert(x);  // 71
  }
  alert(x);  // 31
}

The expression to the right of the equal sign is inside the block. This is different from how let-expressions and let-statements are scoped:

function letTests() {
  let x = 10;

  // let-statement
  let (x = x + 20) {
    alert(x);  // 30
  }

  // let-expression
  alert(let (x = x + 20) x);  // 30

  // let-definition
  {
    let x = x + 20;  // x here evaluates to undefined
    alert(x);  // undefined + 20 ==> NaN
  }
}

At the top level of programs and functions, let behaves exactly like var does. For example:

var x = 'global';
let y = 'global';
console.log(this.x);
console.log(this.y);

The output displayed by this code will display "global" twice.

Note: The global scoping rules of let definitions are likely to change in ES6.

let-scoped variables in for loops

You can use the let keyword to bind variables locally in the scope of for loops. This is different from the var keyword in the head of a for loop, which makes the variables visible in the whole function containing the loop.

var i=0;
for ( let i=i ; i < 10 ; i++ )
  console.log(i);

for ( let [name,value] in Iterator(obj) )
  console.log("Name: " + name + ", Value: " + value);

Scoping rules

for (let expr1; expr2; expr3) statement

In this example, expr2, expr3, and statement are enclosed in an implicit block that contains the block local variables declared by let expr1. This is demonstrated in the first loop above.

for (let expr1 in expr2) statement
for each(let expr1 in expr2) statement

In both these cases, there are implicit blocks containing each statement. The first of these is shown in the second loop above.

Destructuring assignment (Merge into own page/section)

Destructuring assignment makes it possible to extract data from arrays or objects using a syntax that mirrors the construction of array and object literals.

The object and array literal expressions provide an easy way to create ad-hoc packages of data. Once you've created these packages of data, you can use them any way you want to. You can even return them from functions.

One particularly useful thing you can do with destructuring assignment is to read an entire structure in a single statement, although there are a number of interesting things you can do with them, as shown in the section full of examples that follows.

This capability is similar to features present in languages such as Perl and Python.

Examples

Destructuring assignment is best explained through the use of examples, so here are a few for you to read over and learn from.

Avoiding temporary variables

You can use destructuring assignment, for example, to swap values:

var a = 1;
var b = 3;

[a, b] = [b, a];

After executing this code, b is 1 and a is 3. Without destructuring assignment, swapping two values requires a temporary variable (or, in some low-level languages, the XOR-swap trick).

Similarly, it can be used to rotate three or more variables:

var a = 'o', 
    b = "<span style='color:green;'>o</span>", 
    c = 'o', 
    d = 'o', 
    e = 'o', 
    f = "<span style='color:blue;'>o</span>", 
    g = 'o',
    h = 'o';

for ( var lp=0; lp < 40; lp++ ) {

  [a, b, c, d, e, f, g, h] = [b, c, d, e, f, g, h, a];

  document.write(a+''+b+''+c+''+d+''+e+''+f+''+g+''+h+''+"<br />");

}

After executing this code, a visual colorful display of the variable rotation will be displayed.

Returning to our Fibonacci generator example from above, we can eliminate the temporary "t" variable by computing the new values of "i" and "j" in a single group-assignment statement:

function fib() {
  var i = 0, j = 1;
  while (true) {
    yield i;
    [i, j] = [j, i + j];
  }
}

var g = fib();
for (let i = 0; i < 10; i++)
  print(g.next());

Multiple-value returns

Thanks to destructuring assignment, functions can return multiple values. While it's always been possible to return an array from a function, this provides an added degree of flexibility.

function f() {
  return [1, 2];
}

As you can see, returning results is done using an array-like notation, with all the values to return enclosed in brackets. You can return any number of results in this way. In this example, f() returns the values {{ mediawiki.external('1, 2') }} as its output.

var a, b;
[a, b] = f();
console.log("A is " + a + " B is " + b);

The statement {{ mediawiki.external('a, b') }} = f() assigns the results of the function to the variables in brackets, in order: a is set to 1 and b is set to 2.

You can also retrieve the return values as an array:

var a = f();
console.log("A is " + a);

In this case, a is an array containing the values 1 and 2.

Looping across objects

You can also use destructuring assignment to pull data out of an object:

let obj = { width: 3, length: 1.5, color: "orange" };

for (let [name, value] in Iterator(obj)) {
  console.log("Name: " + name + ", Value: " + value);
}

This loops over all the key/value pairs in the object obj and displays their names and values. In this case, the output looks like the following:

Name: width, Value: 3
Name: length, Value: 1.5
Name: color, Value: orange

The Iterator() around obj is not necessary in JavaScript 1.7; however, it is needed for JavaScript 1.8. This is to allow destructuring assignment with arrays (see {{ Bug(366941) }}).

Looping across values in an array of objects

You can loop over an array of objects, pulling out fields of interest from each object:

var people = [
  {
    name: "Mike Smith",
    family: {
      mother: "Jane Smith",
      father: "Harry Smith",
      sister: "Samantha Smith"
    },
    age: 35
  },
  {
    name: "Tom Jones",
    family: {
      mother: "Norah Jones",
      father: "Richard Jones",
      brother: "Howard Jones"
    },
    age: 25
  }
];

for each (let {name: n, family: { father: f } } in people) {
  console.log("Name: " + n + ", Father: " + f);
}

This pulls the name field into n and the family.father field into f, then prints them. This is done for each object in the people array. The output looks like this:

Name: Mike Smith, Father: Harry Smith
Name: Tom Jones, Father: Richard Jones

Pulling fields from objects passed as function parameter

function userId({id}) {
  return id;
}

function whois({displayName: displayName, fullName: {firstName: name}})
  console.log(displayName + " is " + name);
}

var user = {id: 42, displayName: "jdoe", fullName: {firstName: "John", lastName: "Doe"}};

console.log("userId: " + userId(user));
whois(user);

This pulls the id, displayName and firstName from the user object and prints them.

Ignoring some returned values

You can also ignore return values that you're not interested in:

function f() {
  return [1, 2, 3];
}

var [a, , b] = f();
console.log("A is " + a + " B is " + b);

After running this code, a is 1 and b is 3. The value 2 is ignored. You can ignore any (or all) returned values this way. For example:

[,,] = f();

Pulling values from a regular expression match

When the regular expression exec() method finds a match, it returns an array containing first the entire matched portion of the string and then the portions of the string that matched each parenthesized group in the regular expression. Destructuring assignment allows you to pull the parts out of this array easily, ignoring the full match if it is not needed.

// Simple regular expression to match http / https / ftp-style URLs.
var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
if (!parsedURL)
  return null;
var [, protocol, fullhost, fullpath] = parsedURL;u

Quelltext der Version

<div>
  {{ Fx_minversion_header(2) }}</div>
<p>JavaScript 1.7 ist ein Update für die Sprache, womit mehrere neue Features wie Generatoren, Iteratoren, Array-Comprehensions, <code>let</code>-Ausdrücke, und destructing assignments hinzugefügt wurden. Es enthält außerdem alle Features von <a href="/en-US/docs/JavaScript/New_in_JavaScript/1.6" title="en-US/docs/New_in_JavaScript_1.6">JavaScript 1.6</a>.</p>
<p>Die Unterstützung von JavaScript 1.7 beginnt mit Firefox 2.</p>
<p>Die in diesem Artikel enthaltenen Code-Beispiele können in der JavaScript-Shell getestet werden. Lesen Sie <a href="/en-US/docs/SpiderMonkey/Introduction_to_the_JavaScript_shell" title="en-US/docs/Introduction_to_the_JavaScript_shell">Introduction to the JavaScript shell</a>, um mehr über die Benutzung der Shell zu lernen.</p>
<h2 id="Verwendung_von_JavaScript_1.7">Verwendung von JavaScript 1.7</h2>
<p>Möchte man einige der neuen Features von JavaScript 1.7 verwenden, sollte man dies angeben. Bei HTML oder XUL z. B. wie folgt:</p>
<div style="width:auto;overflow:hidden;">
  <pre class="brush: html">
&lt;script type="application/javascript;version=1.7"&gt;&lt;/script&gt;</pre>
</div>
<p>Bei der Verwendung der <a href="/en-US/docs/SpiderMonkey/Introduction_to_the_JavaScript_shell" title="en-US/docs/Introduction_to_the_JavaScript_shell">JavaScript-Shell</a> gibt man die Version über den Parameter <code>-version 170</code> auf der Kommandozeile an oder benutzt die Funktion <code>version()</code>:</p>
<div style="width: auto;overflow:hidden">
  <pre class="brush:js">
version(170);
</pre>
</div>
<p>Neue Features, welche die Benutzung von neuen Schüsselwörtern wie <code>yield</code> und <code>let</code> einschließen, setzen die Versionsangabe voraus, da bei existierendem Code diese Schlüsselwörter eventuell bereits als Bezeichner für Variablen oder Funktionen verwendet werden. Die Features, welche keine neuen Schlüsselwörter einführen (destructing assignments und Array-Comprehensions) können ohne die Versionsangabe verwendet werden.</p>
<h2 id="Generatoren_und_Iteratoren_(siehe_Iteratoren_und_Generatoren)">Generatoren und Iteratoren (siehe <a href="/de/docs/JavaScript/Guide/Iteratoren_und_Generatoren" title="en-US/docs/Core_JavaScript_1.5_Guide/Iterators_and_Generators">Iteratoren und Generatoren</a>)</h2>
<p>Bei der Entwicklung von Code, in dem iterative Algorithmen eingesetzt werden (wie z. B. Iterieren über Listen, XML-Nodes, Datenbank-Ausgaben; oder wiederholtes Verarbeiten desselben Datensatzes) gibt es oft Status-Variablen, deren Werte während des Verbeitungsprozesses verändert werden müssen. Tradiotionell müssen die vorübergehenden Werte dann über eine Callback-Funktion bezogen werden.</p>
<h3 id="Generatoren">Generatoren</h3>
<p>Hier ein Beispiel mit einem iterativer Algorithmus für die Berechnung von Fibonacci-Zahlen:</p>
<div style="width: auto;overflow:hidden">
  <pre class="brush:js">
function do_callback(num) {
  console.log(num);
}

function fib() {
  var i = 0, j = 1, n = 0;
  while (n &lt; 10) {
    do_callback(i);
    var t = i;
    i = j;
    j += t;
    n++;
  }
}

fib();
</pre>
</div>
<p>Bei diesem Code kommt eine Callback-Routine zum Einsatz, um bei jedem iterativen Schritt des Algorithmus bestimmte Operationen durchzuführen. In diesem Fall wird jede Fibonacci-Zahl einfach auf der Konsole ausgegeben.</p>
<p>Generatoren und Iteratoren arbeiten zusammen, um dies besser umzusetzen. Im Anschluss ein Beispiel zur Berechnung von Fibonacci-Zahlen unter Einsatz eines Generators:</p>
<pre class="brush:js">
function fib() {
  var i = 0, j = 1;
  while (true) {
    yield i;
    var t = i;
    i = j;
    j += t;
  }
}

var g = fib();
for (var i = 0; i &lt; 10; i++) {
  console.log(g.next());
}
</pre>
<p>Bei der Funktion, welche das Schlüsselwort <code>yield</code> enthält, handelt es sich um einen Generator. Beim Aufruf dieser Funktion werden ihre formalen Parameter an aktuelle Argumente gebunden, aber der Code nicht ausgeführt, sondern stattdessen ein Generator-Iterator zurückgegeben. Bei jedem Aufruf der <code>next()</code>-Methode des Generator-Iterators wird dann ein weiterer Iterationsschritt ausgeführt. Der Rückgabewert jedes Durchlaufs ist der nach <code>yield</code> stehende Wert. Man kann sich <code>yield</code> ungefähr wie eine spezielles <code>return</code> für Generator-Iterator-Objekte vorstellen, welches die Begrenzung für jeden Iterationsschritt festlegt. Bei jedem Aufruf von <code>next()</code> wird die Ausführung dann bei der Anweisung nach <code>yield</code> fortgesetzt.</p>
<p>Ein Generator-Iterator wird durchlaufen, indem die Methode <code>next()</code> wiederholt aufgerufen wird, solange bis schließlich das gewünscht Ergebnis erreicht bzw. die Bedingung erfüllt ist. Bei dem Beispiel mit den Fibonacci-Zahlen ruft man also wiederholt <code>g.next()</code> auf, bis man die gewünschte Anzahl von Fibonacci-Zahlen erzeugt hat.</p>
<h4 id="Fortsetzen_eines_Generators_an_einem_bestimmten_Punkt">Fortsetzen eines Generators an einem bestimmten Punkt</h4>
<p>Sobald ein Generator einmal durch den Aufruf der <code>next()</code>-Methode gestartet wurde, kann der Methode <code>send()</code> ein beliebiger Wert an den Generator übergeben werden. Dieser Wert wird dann so interpriert, als wäre es der Wert des letzten <code>yield</code>. Der Generator gibt dann den Operanden des darauf folgenden <code>yield</code> zurück.</p>
<p>Ein Generator lässt sich nicht an einem bestimtmen Punkt starten, sondern nur über die Methode <code>next()</code>. Erst nach dem <code>next()</code>-Aufruf kann über <code>send()</code> ein Wert gesetzt werden.</p>
<div class="note">
  <strong>Achtung:</strong> Der Aufruf von <code>send(undefined)</code> ist äquivalent zum Aufruf von <code>next()</code>. Jeder Start eines neuen Generator über <code>send()</code> mit einem anderen Wert als undefined resultiert jedoch in einem <code>TypeError</code>-Ausnahmefehler.</div>
<h4 id="Ausnahmen_bei_Generatoren">Ausnahmen bei Generatoren</h4>
<p>Man kann einen Generator dazu bringen, eine Ausnahme auszuwerfen, indem man seine <code>throw()</code>-Methode aufruft und einen Wert übergibt, der ausgeworfen werden soll. Diese Ausnahme wird unter Einbeziehung des Kontext der aktuellen Unterbrechung ausgeworfen, so als wäre das <code>yield</code> des aktuellen Durchlaufs eine Anweisung <code>throw Wert</code><code><em>.</em></code></p>
<p>Trifft die Ausführung während der Verarbeitung der ausgeworfenen Ausnahme auf kein <code>yield</code>, so verbreitet sich die Ausnahme bis nach oben durch den Aufruf bis zu <code>next()</code> und nachfolgende Aufrufe von <code>next()</code> lösen eine <code>StopIteration</code>-Ausnahme aus.</p>
<h4 id="Schlie.C3.9Fen_eines_Generators">Schließen eines Generators</h4>
<p>Generatoren besitzen eine Methode <code>close()</code>, welche den Generator zwingt, sich selbst zu schließen. Die Effekte einer solchen Schließung sind folgende:</p>
<ol>
  <li>Jede <code>finally</code>-Klausel, die in der Generator-Funktion aktiv ist, wird ausgeführt.</li>
  <li>Wird durch eine <code>finally</code>-Klausel eine andere Ausnahme als<code> StopIteration</code> ausgeworfen, wird diese an die Funktion weitergeleitet, die <code>close()</code> aufgerufen hat.</li>
  <li>Der Generator terminiert.</li>
</ol>
<h4 id="Generator-Beispiel">Generator-Beispiel</h4>
<p>Dieser Code arbeitet mit einem Generator, der alle 100 Schleifendurchläufe etwas "abwirft" (yield = abwerfen):</p>
<pre class="brush:js">
var gen = generator();

function driveGenerator() {
  if (gen.next()) {
    window.setTimeout(driveGenerator, 0);	
  } else {
    gen.close();	
  }
}

function generator() {
  while (i &lt; something) {
    /** stuff **/

    ++i;
    /** 100 loops per yield **/
    if ((i % 100) == 0) {
      yield true;
    } 
  }
  yield false;
}
</pre>
<h3 id="Iteratoren">Iteratoren</h3>
<p>Ein <em>Iterator</em> ist ein spezielles Objekt, das es erlaubt über Daten zu iterieren.</p>
<p>Bei der normalen Benutzung sind Iterator-Objekte "unsichtbar"; man braucht sie nicht explizit abzusprechen, sondern setzt stattdessen <a href="/en-US/docs/JavaScript/Guide/Statements#Object_Manipulation_Statements" title="en-US/docs/JavaScript/Guide/Statements#Object Manipulation Statements"><code>for...in</code> und <code>for each...in</code> Anweisungen</a> ein, um über Schlüssel und/oder Werte von Objekten zu iterieren.</p>
<pre class="brush:js">
var objectWithIterator = getObjectSomehow();

for (var i in objectWithIterator)
{
  console.log(objectWithIterator[i]);
}
</pre>
<p>Für die Implementierung eines eigenen Iterator-Objekts oder zur direkten Veränderung von Iteratoren sollte man über die <code>next()</code>-Methode, die <code>StopIteration</code>-Ausnahme und die <code>__iterator__</code>-Methode informiert sein.</p>
<p>Ein Iterator für ein Objekt kann man mit dem Aufruf von <code>Iterator(<em>objectname</em>)</code>; erzeugen. Der Iterator kann über die Methode <code>__iterator__</code> gefunden werden; ist diese Methode nicht vorhanden, wird ein Default-Iterator erstellt. Der Default-Iterator wirft über <code>yield</code> die Eigenschaften des Objekts ab. Möchte man stattdessen einen selbstdefinierten Iterator einsetzen, überschreibt man die Methode <code>__iterator__</code>, damit diese eine Instanz des selbstbefinierten Iterators zurückgibt. Um den Iterator eines Objekts über ein Skript abzufragen, sollte man auf <code>Iterator(obj)</code> statt direkt auf <code>__iterator__</code> zurückgreifen. Ersteres funktioniert für Arrays, letzteres nicht.</p>
<p>Nach Erzeugung des Iterators kann man einfach über die Methode <code>next()</code> das nächste Element abfragen. Sind keine Daten mehr vorhanden, wird eine <code>StopIteration</code>-Ausnahme ausgeworfen.</p>
<p>Hier ein einfaches Beispiel für die direkte Manipulation eines Iterators:</p>
<pre class="brush:js">
var obj = {name:"Jack Bauer", username:"JackB", id:12345, agency:"CTU",
          region:"Los Angeles"};

var it = Iterator(obj);

try {
  while (true) {
    print(it.next() + "\n");
  }
} catch (err if err instanceof StopIteration) {
  print("End of record.\n");
} catch (err) {
  print("Unknown error: " + err.description + "\n");
}
</pre>
<p>Die Ausgabe dieses Codes ist wie folgt:</p>
<pre class="eval">
name,Jack Bauer
username,JackB
id,12345
agency,CTU
region,Los Angeles
End of record.
</pre>
<p>Optional kann man bei der Erstellung eines Iterators einen booleschen Wert als zweiten Parameter angeben, womit festgelegt wird, ob nur der jeweilge Schlüssel beim Aufruf der <code>next()</code>-Methode zurückgegeben werden soll. Der Paramater wird an benutzerdefinierte <code>__iterator__</code>-Funktionen als einziges Argument übergeben. Würde man beim Beispiel oben die Anweisung <code>var it = Iterator(obj);</code> in <code>var it = Iterator(obj, true);</code> ändern, würde man folgende Ausgabe erhalten:</p>
<pre>
name
username
id
agency
region
End of record.
</pre>
<p>In beiden Fällen kann die Reihenfolge der Datenausgabe je nach Implemetierung variieren. Es gibt keine Garantie für eine bestimmte Anordung der ausgegebenen Daten.</p>
<p>Iteroren sind nützlich, um die Daten in einem Objekt abzufragen. Solche Objekte, die Daten enthalten, von denen man zunächst nicht weiß, eingeschlossen. Das kann hilfreich sein, wenn man Daten hinterlegen muss, die von einer Applikation nicht erwartet werden.</p>
<h2 id="Array-Comprehensions_(siehe_Array_comprehensions)">Array-Comprehensions (siehe <a href="/en-US/docs/JavaScript/Guide/Predefined_Core_Objects#Array_comprehensions" title="en-US/docs/JavaScript/Guide/Predefined_Core_Objects#Array_comprehensions">Array comprehensions</a>)</h2>
<p>Array-Comprehensions nutzen Generatoren für die effiziente Initialisierung von Arrays. Zum Beispiel:</p>
<pre class="brush:js">
function range(begin, end) {
  for (let i = begin; i &lt; end; ++i) {
    yield i;
  }
}
</pre>
<p><code>range()</code> ist ein Generator, der alle Werte zwischen <var>begin</var> und <var>end</var> zurückgibt. Nach der Definition kann der Generator wie folgt benutzt werden:</p>
<pre class="brush:js">
var ten_squares = [i * i for each (i in range(0, 10))];
</pre>
<p>Damit wird ein Array <em>ten_squares</em> vorinitialisiert, welches die Qudratzahlen der Werte von <code>0</code> bis <code>9</code> enthält.</p>
<p>Bei der Initialisierung können beliebige Bedingungen angegeben werden. Mit folgendem Code wird z. B. ein Array initialisiert, welches die geraden Zahlen zwischen 0 und 20 enthält:</p>
<pre class="brush:js">
var evens = [i for each (i in range(0, 21)) if (i % 2 == 0)];
</pre>
<p>Bei Versionen vor JavaScript 1.7 würde man dies ungefähr so umsetzen:</p>
<pre class="brush:js">
var evens = [];
for (var i=0; i &lt;= 20; i++) {
  if (i % 2 == 0)
    evens.push(i);
}
</pre>
<p>Die Array-Comprehension ist nicht nur kompakter, sondern auch lesbarer, sobald man das Konzept einmal verstanden hat.</p>
<h3 id="Regeln_f.C3.BCr_die_Sichtbarkeit_(Scope)">Regeln für die Sichtbarkeit (Scope)</h3>
<p>Array-Comprehensions sind von einen impliziten Block abgegrenzt, der alles, was zwischen den eckige Klammern steht, enthält; inklusive impliziter let-Deklarationen.</p>
<h2 id="Block-Begrenzungen_mit_let_(siehe_let_Statement)">Block-Begrenzungen mit <code>let</code> (siehe <a href="/en-US/docs/JavaScript/Reference/Statements/let" title="en-US/docs/JavaScript/Reference/Statements/let"><code>let</code> Statement</a>)</h2>
<p>There are several ways in which <code>let</code> can be used to manage block scope of data and functions:</p>
<ul>
  <li>The <a href="#let_statement"><strong><code>let</code> statement</strong></a> provides a way to associate values with variables within the scope of a block, without affecting the values of like-named variables outside the block.</li>
  <li>The <a href="#let_expressions"><strong><code>let</code> expression</strong></a> lets you establish variables scoped only to a single expression.</li>
  <li>The <a href="#let_definitions"><strong><code>let</code> definition</strong></a> defines variables whose scope is constrained to the block in which they're defined. This syntax is very much like the syntax used for <code>var</code>.</li>
  <li>You can also use <code>let</code> to <a href="#let-scoped_variables_in_for_loops">establish variables that exist only within the context of a <code>for</code> loop</a>.</li>
</ul>
<h3 id="let_statement"><code>let</code> statement</h3>
<p>The <code>let</code> statement provides local scoping for variables. It works by binding zero or more variables in the lexical scope of a single block of code; otherwise, it is exactly the same as a <a href="/en-US/docs/JavaScript/Reference/Statements/block" title="en-US/docs/Core_JavaScript_1.5_Reference/Statements/block">block statement</a>. Note in particular that the scope of a variable declared inside a <code>let</code> statement using <code>var</code> is still the same as if it had been declared outside the <code>let</code> statement; such variables still have function scoping.</p>
<p>For example:</p>
<pre class="brush:js">
var x = 5;
var y = 0;

let (x = x+10, y = 12) {
  console.log(x+y); // 27
}

console.log(x + y); // 5
</pre>
<p>The rules for the code block are the same as for any other code block in JavaScript. It may have its own local variables established using the <code>let</code> declarations.</p>
<div class="note">
  <strong>Note:</strong> When using the <code>let</code> statement syntax, the parentheses following <code>let</code> are required. Failure to include them will result in a syntax error.</div>
<h4 id="Scoping_rules">Scoping rules</h4>
<p>The scope of variables defined using <code>let</code> is the <code>let</code> block itself, as well as any inner blocks contained inside it, unless those blocks define variables by the same names.</p>
<h3 id="let_expressions"><code>let</code> expressions</h3>
<p>You can use <code>let</code> to establish variables that are scoped only to a single expression:</p>
<pre class="brush:js">
var x = 5;
var y = 0;
console.log(let(x = x + 10, y = 12) x + y);
console.log(x + y);
</pre>
<p>The resulting output is:</p>
<pre>
27
5
</pre>
<p>In this case, the binding of the values of <var>x</var> and <var>y</var> to <code>x+10</code> and <code>12</code> are scoped solely to the expression <code>x + y + "&lt;br&gt;\n"</code>.</p>
<h4 id="Scoping_rules">Scoping rules</h4>
<p>Given a <code>let</code> expression:</p>
<pre class="eval">
let (<var>decls</var>) <var style="color: blue;">expr</var>
</pre>
<p>There is an implicit block created around <var style="color: blue;">expr</var>.</p>
<h3 id="let_definitions"><code>let</code> definitions</h3>
<p>The <code>let</code> keyword can also be used to define variables inside a block.</p>
<div class="note">
  <strong>Note:</strong> If you have more interesting examples of ways to use <code>let</code> definitions, please consider adding them here.</div>
<pre class="brush:js">
if (x &gt; y) {
  let gamma = 12.7 + y;
  i = gamma * x;
}
</pre>
<p>You can use <code>let</code> definitions to alias pseudo-namespaced code in extensions. (See <a href="/en-US/docs/Security_best_practices_in_extensions" title="en-US/docs/Security_best_practices_in_extensions">Security best practices in extensions</a>.)</p>
<pre class="brush:js">
let Cc = Components.classes, Ci = Components.interfaces;
</pre>
<p><code>let</code> statements, expressions and definitions sometimes make the code cleaner when inner functions are used.</p>
<pre class="brush:js">
var list = document.getElementById("list");

for (var i = 1; i &lt;= 5; i++) {
  var item = document.createElement("LI");
  item.appendChild(document.createTextNode("Item " + i));

  let j = i;
  item.onclick = function (ev) {
    alert("Item " + j + " is clicked.");
  };
  list.appendChild(item);
}
</pre>
<p>The example above works as intended because the five instances of the (anonymous) inner function refer to five different instances of variable <code>j</code>. Note that it does not work as intended if you replace <code>let</code> by <code>var</code> or if you remove the variable <code>j</code> and simply use the variable <code>i</code> in the inner function.</p>
<h4 id="Scoping_rules">Scoping rules</h4>
<p>Variables declared by <code>let</code> have as their scope the block in which they are defined, as well as in any sub-blocks in which they aren't redefined. In this way, <code>let</code> works very much like <code>var</code>. The main difference is that the scope of a <code>var</code> variable is the entire enclosing function:</p>
<pre class="brush:js">
function varTest() {
  var x = 31;
  if (true) {
    var x = 71;  // same variable!
    alert(x);  // 71
  }
  alert(x);  // 71
}

function letTest() {
  let x = 31;
  if (true) {
    let x = 71;  // different variable
    alert(x);  // 71
  }
  alert(x);  // 31
}
</pre>
<p>The expression to the right of the equal sign is inside the block. This is different from how <code>let</code>-expressions and <code>let</code>-statements are scoped:</p>
<pre class="brush:js">
function letTests() {
  let x = 10;

  // let-statement
  let (x = x + 20) {
    alert(x);  // 30
  }

  // let-expression
  alert(let (x = x + 20) x);  // 30

  // let-definition
  {
    let x = x + 20;  // x here evaluates to undefined
    alert(x);  // undefined + 20 ==&gt; NaN
  }
}
</pre>
<p>At the top level of programs and functions, <code>let</code> behaves exactly like <code>var</code> does. For example:</p>
<pre class="brush:js">
var x = 'global';
let y = 'global';
console.log(this.x);
console.log(this.y);
</pre>
<p>The output displayed by this code will display "global" twice.</p>
<div class="note">
  <strong>Note:</strong> The global scoping rules of <code>let</code> definitions are likely to change in ES6.</div>
<h3 id="let-scoped_variables_in_for_loops"><code>let</code>-scoped variables in <code>for</code> loops</h3>
<p>You can use the <code>let</code> keyword to bind variables locally in the scope of <code>for</code> loops. This is different from the var keyword in the head of a for loop, which makes the variables visible in the whole function containing the loop.</p>
<pre class="brush:js">
var i=0;
for ( let i=i ; i &lt; 10 ; i++ )
  console.log(i);

for ( let [name,value] in Iterator(obj) )
  console.log("Name: " + name + ", Value: " + value);
</pre>
<h4 id="Scoping_rules">Scoping rules</h4>
<pre class="eval">
for (let <var>expr1</var>; <var style="color: blue;">expr2</var>; <var style="color: blue;">expr3</var>) <var style="color: blue;">statement</var>
</pre>
<p>In this example, <var style="color: blue;">expr2</var>, <var style="color: blue;">expr3</var>, and <var style="color: blue;">statement</var> are enclosed in an implicit block that contains the block local variables declared by <code>let <var>expr1</var></code>. This is demonstrated in the first loop above.</p>
<pre class="eval">
for (let <var>expr1</var> in <var>expr2</var>) <var style="color: blue;">statement</var>
for each(let <var>expr1</var> in <var>expr2</var>) <var style="color: blue;">statement</var>
</pre>
<p>In both these cases, there are implicit blocks containing each <var style="color: blue;">statement</var>. The first of these is shown in the second loop above.</p>
<h2 id="Destructuring_assignment_(Merge_into_own_page.2Fsection)"><a href="/en-US/docs/JavaScript/Syntax/Destructuring_assignment" title="/en-US/docs/JavaScript/Syntax/Destructuring_assignment">Destructuring assignment</a> (Merge into own page/section)</h2>
<p>Destructuring assignment makes it possible to extract data from arrays or objects using a syntax that mirrors the construction of array and object literals.</p>
<p>The object and array literal expressions provide an easy way to create ad-hoc packages of data. Once you've created these packages of data, you can use them any way you want to. You can even return them from functions.</p>
<p>One particularly useful thing you can do with destructuring assignment is to read an entire structure in a single statement, although there are a number of interesting things you can do with them, as shown in the section full of examples that follows.</p>
<p>This capability is similar to features present in languages such as Perl and Python.</p>
<h3 id="Examples">Examples</h3>
<p>Destructuring assignment is best explained through the use of examples, so here are a few for you to read over and learn from.</p>
<h4 id="Avoiding_temporary_variables">Avoiding temporary variables</h4>
<p>You can use destructuring assignment, for example, to swap values:</p>
<pre class="brush:js">
var a = 1;
var b = 3;

[a, b] = [b, a];
</pre>
<p>After executing this code, <var>b</var> is 1 and <var>a</var> is 3. Without destructuring assignment, swapping two values requires a temporary variable (or, in some low-level languages, the <a class="external" href="http://en.wikipedia.org/wiki/XOR_swap">XOR-swap trick</a>).</p>
<p>Similarly, it can be used to rotate three or more variables:</p>
<pre class="brush:js">
var a = 'o', 
    b = "&lt;span style='color:green;'&gt;o&lt;/span&gt;", 
    c = 'o', 
    d = 'o', 
    e = 'o', 
    f = "&lt;span style='color:blue;'&gt;o&lt;/span&gt;", 
    g = 'o',
    h = 'o';

for ( var lp=0; lp &lt; 40; lp++ ) {

  [a, b, c, d, e, f, g, h] = [b, c, d, e, f, g, h, a];

  document.write(a+''+b+''+c+''+d+''+e+''+f+''+g+''+h+''+"&lt;br /&gt;");

}
</pre>
<p>After executing this code, a visual colorful display of the variable rotation will be displayed.</p>
<p>Returning to our Fibonacci generator example from above, we can eliminate the temporary "t" variable by computing the new values of "i" and "j" in a single group-assignment statement:</p>
<pre class="brush:js">
function fib() {
  var i = 0, j = 1;
  while (true) {
    yield i;
    [i, j] = [j, i + j];
  }
}

var g = fib();
for (let i = 0; i &lt; 10; i++)
  print(g.next());
</pre>
<h4 id="Multiple-value_returns">Multiple-value returns</h4>
<p>Thanks to destructuring assignment, functions can return multiple values. While it's always been possible to return an array from a function, this provides an added degree of flexibility.</p>
<pre class="brush:js">
function f() {
  return [1, 2];
}
</pre>
<p>As you can see, returning results is done using an array-like notation, with all the values to return enclosed in brackets. You can return any number of results in this way. In this example, <code>f()</code> returns the values <code>{{ mediawiki.external('1, 2') }}</code> as its output.</p>
<pre class="brush:js">
var a, b;
[a, b] = f();
console.log("A is " + a + " B is " + b);
</pre>
<p>The statement <code>{{ mediawiki.external('a, b') }} = f()</code> assigns the results of the function to the variables in brackets, in order: <var>a</var> is set to 1 and <var>b</var> is set to 2.</p>
<p>You can also retrieve the return values as an array:</p>
<pre class="brush:js">
var a = f();
console.log("A is " + a);
</pre>
<p>In this case, <var>a</var> is an array containing the values 1 and 2.</p>
<h4 id="Looping_across_objects">Looping across objects</h4>
<p>You can also use destructuring assignment to pull data out of an object:</p>
<pre class="brush:js">
let obj = { width: 3, length: 1.5, color: "orange" };

for (let [name, value] in Iterator(obj)) {
  console.log("Name: " + name + ", Value: " + value);
}
</pre>
<p>This loops over all the key/value pairs in the object <var>obj</var> and displays their names and values. In this case, the output looks like the following:</p>
<pre class="eval">
Name: width, Value: 3
Name: length, Value: 1.5
Name: color, Value: orange
</pre>
<p>The <code>Iterator()</code> around <code>obj</code> is not necessary in JavaScript 1.7; however, it is needed for <a href="/en-US/docs/JavaScript/New_in_JavaScript/1.8" title="en-US/docs/New_in_JavaScript_1.8">JavaScript 1.8</a>. This is to allow destructuring assignment with arrays (see {{ Bug(366941) }}).</p>
<h4 id="Looping_across_values_in_an_array_of_objects">Looping across values in an array of objects</h4>
<p>You can loop over an array of objects, pulling out fields of interest from each object:</p>
<pre class="brush:js">
var people = [
  {
    name: "Mike Smith",
    family: {
      mother: "Jane Smith",
      father: "Harry Smith",
      sister: "Samantha Smith"
    },
    age: 35
  },
  {
    name: "Tom Jones",
    family: {
      mother: "Norah Jones",
      father: "Richard Jones",
      brother: "Howard Jones"
    },
    age: 25
  }
];

for each (let {name: n, family: { father: f } } in people) {
  console.log("Name: " + n + ", Father: " + f);
}
</pre>
<p>This pulls the <var>name</var> field into <var>n</var> and the <var>family.father</var> field into <var>f</var>, then prints them. This is done for each object in the <var>people</var> array. The output looks like this:</p>
<pre>
Name: Mike Smith, Father: Harry Smith
Name: Tom Jones, Father: Richard Jones</pre>
<h4 id="Pulling_fields_from_objects_passed_as_function_parameter">Pulling fields from objects passed as function parameter</h4>
<pre class="brush:js">
function userId({id}) {
  return id;
}

function whois({displayName: displayName, fullName: {firstName: name}})
  console.log(displayName + " is " + name);
}

var user = {id: 42, displayName: "jdoe", fullName: {firstName: "John", lastName: "Doe"}};

console.log("userId: " + userId(user));
whois(user);</pre>
<p>This pulls the <code>id</code>, <code>displayName</code> and<span class="Apple-converted-space"> </span><code>firstName</code><span class="Apple-converted-space"> </span>from the user object and prints them.</p>
<h4 id="Ignoring_some_returned_values">Ignoring some returned values</h4>
<p>You can also ignore return values that you're not interested in:</p>
<pre class="brush:js">
function f() {
  return [1, 2, 3];
}

var [a, , b] = f();
console.log("A is " + a + " B is " + b);
</pre>
<p>After running this code, a is 1 and b is 3. The value 2 is ignored. You can ignore any (or all) returned values this way. For example:</p>
<pre class="brush:js">
[,,] = f();
</pre>
<h4 id="Pulling_values_from_a_regular_expression_match">Pulling values from a regular expression match</h4>
<p>When the regular expression <code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec" title="en-US/docs/Core_JavaScript_1.5_Reference/Global_Objects/RegExp/exec"> exec()</a></code> method finds a match, it returns an array containing first the entire matched portion of the string and then the portions of the string that matched each parenthesized group in the regular expression. Destructuring assignment allows you to pull the parts out of this array easily, ignoring the full match if it is not needed.</p>
<pre class="brush:js">
// Simple regular expression to match http / https / ftp-style URLs.
var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
if (!parsedURL)
  return null;
var [, protocol, fullhost, fullpath] = parsedURL;u</pre>
Zu dieser Version zurücksetzen