diff --git a/1-js/02-first-steps/15-function-expressions/article.md b/1-js/02-first-steps/15-function-expressions/article.md index a8ccd6c6c..03e98046f 100644 --- a/1-js/02-first-steps/15-function-expressions/article.md +++ b/1-js/02-first-steps/15-function-expressions/article.md @@ -1,8 +1,8 @@ -# Function expressions +# Function Expressions -In JavaScript, a function is not a "magical language structure", but a special kind of value. +In JavaScript ist eine Funktion keine "magische Sprachstruktur", sondern eine besondere Art Wert. -The syntax that we used before is called a *Function Declaration*: +Bisher haben wir die Syntax *Function Declaration* benutzt. ```js function sayHi() { @@ -10,9 +10,9 @@ function sayHi() { } ``` -There is another syntax for creating a function that is called a *Function Expression*. +Es gibt allerdings auch die Syntax namens *Function Expression* -It looks like this: +Diese sieht so aus: ```js let sayHi = function() { @@ -20,11 +20,11 @@ let sayHi = function() { }; ``` -Here, the function is created and assigned to the variable explicitly, like any other value. No matter how the function is defined, it's just a value stored in the variable `sayHi`. +Hier wird die Funktion erstellt und einer Variable explizit zugewiesen, wie jeder andere Wert. Unabhängig davon, wie die Funktion definiert ist, ist sie nur ein Wert, den wir in der variable `sayHi` speichern. -The meaning of these code samples is the same: "create a function and put it into the variable `sayHi`". +Die Bedeutung beider Codebeispiele ist dieselbe: "erstelle eine Funktion und schreibe sie in die Variable `sayHi`". -We can even print out that value using `alert`: +Wir können uns diesen Wert mit dem Befehl `alert` auch anzeigen lassen: ```js run function sayHi() { @@ -32,39 +32,36 @@ function sayHi() { } *!* -alert( sayHi ); // shows the function code +alert( sayHi ); // zeigt die Funktion als String */!* ``` -Please note that the last line does not run the function, because there are no parentheses after `sayHi`. There are programming languages where any mention of a function name causes its execution, but JavaScript is not like that. +Interessanterweise führt die letzte Zeile die Funktion nicht aus, denn hinter `sayHi` befinden sich keine Klammern. In einigen Programmiersprachen führt jede Erwähnung einer Funktion zur Ausführung, JavaScript gehört nicht dazu. -In JavaScript, a function is a value, so we can deal with it as a value. The code above shows its string representation, which is the source code. +In JavaScript ist eine Funktion ein Wert, also können wir damit auch umgehen, wie mit einem Wert. Der obige code zeigt die Funktion als String an, zeigt also den Quellcode. +Sicher, eine Funktion ist ein besonderer Wert, denn wir können sie aufrufen, z.B. mit `sayHi()`. -Surely, a function is a special value, in the sense that we can call it like `sayHi()`. - -But it's still a value. So we can work with it like with other kinds of values. - -We can copy a function to another variable: +Sie bleibt aber ein Wert. Darum können wir mit Funktionen genau so arbeiten wie mit anderen Werten. +Wir können Funktionen in eine Variable kopieren: ```js run no-beautify -function sayHi() { // (1) create +function sayHi() { // (1) erstellen alert( "Hello" ); } -let func = sayHi; // (2) copy +let func = sayHi; // (2) kopieren -func(); // Hello // (3) run the copy (it works)! -sayHi(); // Hello // this still works too (why wouldn't it) +func(); // Hello // (3) Kopie ausführen(klappt)! +sayHi(); // Hello // Die Funktion funktioniert immernoch (warum auch nicht?) ``` -Here's what happens above in detail: - -1. The Function Declaration `(1)` creates the function and puts it into the variable named `sayHi`. -2. Line `(2)` copies it into the variable `func`. Please note again: there are no parentheses after `sayHi`. If there were, then `func = sayHi()` would write *the result of the call* `sayHi()` into `func`, not *the function* `sayHi` itself. -3. Now the function can be called as both `sayHi()` and `func()`. +Das hier passiert oben im Detail: -Note that we could also have used a Function Expression to declare `sayHi`, in the first line: +1. Die Function Declaration `(1)` definiert die Funktion und schreibt sie in die Variable `sayHi`. +2. Zeile `(2)` kopiert sie in die Variable `func`. Wieder verwenden wir *keine* Klammern nach `sayHi`. Wenn wir Klammern verwenden würden, dann würde `func = sayHi()` das *Ergebnis des Aufrufs* `sayHi()` in Variable `func`kopieren, nicht den Quellcode selbst. +3. Jetzt kann die Funktion unter beiden Namen `sayHi()` und `func()` aufgerufen werden. +Wir hätten in der ersten Zeile auch die Syntax Function Expression nutzen können um `sayHi` zu definieren: ```js let sayHi = function() { alert( "Hello" ); @@ -74,11 +71,11 @@ let func = sayHi; // ... ``` -Everything would work the same. +Alles würde gleich funktionieren. -````smart header="Why is there a semicolon at the end?" -You might wonder, why does Function Expression have a semicolon `;` at the end, but Function Declaration does not: +````smart header="Wieso ist da ein Semikolon am Ende?" +Man könnte sich fragen, wieso Function Expressions einen Semicolon `;` am Ende benötigen und Function Declarations nicht. ```js function sayHi() { @@ -90,100 +87,95 @@ let sayHi = function() { }*!*;*/!* ``` -The answer is simple: -- There's no need for `;` at the end of code blocks and syntax structures that use them like `if { ... }`, `for { }`, `function f { }` etc. -- A Function Expression is used inside the statement: `let sayHi = ...;`, as a value. It's not a code block, but rather an assignment. The semicolon `;` is recommended at the end of statements, no matter what the value is. So the semicolon here is not related to the Function Expression itself, it just terminates the statement. +Die Antwort ist: +- Man benötigt keinen semicolon `;` am Ende von Blöcken und syntaktischen Strukturen, die `if { ... }`, `for { }`, `function f { }` etc. verwenden. +- Eine Function Expression dagegen wird im Befehl `let sayHi = ...;` als Wert verwandt. Es ist kein Block Code, sondern eine Zuweisung. Der Semicolon `;` ist am Ende von Statements empfohlen, egal was der Wert ist. Der Semicolon `;` hat an dieser Stelle also nichts mit der Funktion zu tun, sondern beendet nur das Statement. ```` -## Callback functions +## Callback Funktionen -Let's look at more examples of passing functions as values and using function expressions. +Schauen wir uns noch einige Beispiele an, in denen funktionen als Werte weitergegeben und in Funktionsausdrücken genutzt werden. -We'll write a function `ask(question, yes, no)` with three parameters: +Wir schreiben eine Funktion `ask(Frage, ja, nein)` mit drei Parametern: -`question` -: Text of the question +`Frage` +: Fragetext -`yes` -: Function to run if the answer is "Yes" +`ja` +: Funktion, die laufen soll, wenn bestätigt wurde. -`no` -: Function to run if the answer is "No" - -The function should ask the `question` and, depending on the user's answer, call `yes()` or `no()`: +`nein` +: Funktion, die laufen soll, wenn abgelehnt wurde. +Die Funktion soll die `Frage` fragen und, je nach der Antwort der Nutzerin, `ja()` oder `nein()` aufrufen: ```js run *!* -function ask(question, yes, no) { - if (confirm(question)) yes() - else no(); +function ask(Frage, ja, nein) { + if (confirm(Frage)) ja() + else nein(); } + */!* function showOk() { - alert( "You agreed." ); + alert( "Einverstanden!" ); } function showCancel() { - alert( "You canceled the execution." ); + alert( "Abbruch!" ); } -// usage: functions showOk, showCancel are passed as arguments to ask -ask("Do you agree?", showOk, showCancel); +// Benutzung: die Funktionen showOk, showCancel werden ask als Funktionsargument weitergegeben +ask("Einverstanden?", showOk, showCancel); ``` -In practice, such functions are quite useful. The major difference between a real-life `ask` and the example above is that real-life functions use more complex ways to interact with the user than a simple `confirm`. In the browser, such function usually draws a nice-looking question window. But that's another story. - -**The arguments `showOk` and `showCancel` of `ask` are called *callback functions* or just *callbacks*.** +In der Praxis sind solche Funktionen sehr nützlich. Der Hauptunterschied zwischen einem "professionellen" `ask` und dem Beispiel ist, dass "professionelle" Funktionen kompliziertere Verfahren nutzen, um mit dem Nutzer zu interagieren als ein einfaches `confirm`. Im browser erstellt eine solche Funktion normal ein schickes Fragefenster. Aber das ist eine andere Baustelle. -The idea is that we pass a function and expect it to be "called back" later if necessary. In our case, `showOk` becomes the callback for "yes" answer, and `showCancel` for "no" answer. +**Die Argumente `showOK`und `shoeCancel` nennt man *Callback Funktionen* oder einfach *Callbacks*. ** -We can use Function Expressions to write the same function much shorter: +Dabei geht es darum, dass wir eine Funktion vorgeben, die später aufgerufen werden soll, falls nötig. In unserem Fall, `showOK` wird aufgerufen, wenn der User bestätigt, `showCancel` wenn der User ablehnt. +Wir können Funktionsausdrücke verwenden, um dieselbe Funktion deutlich zu verkürzen: ```js run no-beautify -function ask(question, yes, no) { - if (confirm(question)) yes() - else no(); +function ask(Frage, ja, nein) { + if (confirm(Frage)) ja() + else nein(); } *!* ask( - "Do you agree?", - function() { alert("You agreed."); }, - function() { alert("You canceled the execution."); } + "Einverstanden?", + function() { alert("Einverstanden!"); }, + function() { alert("Abbruch."); } ); */!* ``` -Here, functions are declared right inside the `ask(...)` call. They have no name, and so are called *anonymous*. Such functions are not accessible outside of `ask` (because they are not assigned to variables), but that's just what we want here. +Wir deklarieren die Funktionen direkt im Aufruf von `ask` . Sie haben keinen Namen, weshalb sie als *anonym* bezeichnet werden. Solche Funktionen sind nicht außerhalb von `ask` aufrufbar (denn sie sind keiner Variable zugeordnet), aber das ist genau, was wir hier brauchen. -Such code appears in our scripts very naturally, it's in the spirit of JavaScript. +Solcher Code taucht in unseren Programmen natürllicherweise auf, es ist die Essez von JavaScript. -```smart header="A function is a value representing an \"action\"" -Regular values like strings or numbers represent the *data*. +```smart header="Eine Funktion ist ein Wert, der eine \"Aktion\" repräsentiert" +Normale Werte wie Strings oder Zahlen repräsentieren die "Daten". +Eine Funktion ist also eine *Aktion* -A function can be perceived as an *action*. - -We can pass it between variables and run when we want. +Wir könne sie zwischen den Variablen verschieben und nutzen, wann wir wollen. ``` ## Function Expression vs Function Declaration +Was sind die Kernunterschiede zwischen Function Declarations und Function Expressions? -Let's formulate the key differences between Function Declarations and Expressions. - -First, the syntax: how to differentiate between them in the code. - -- *Function Declaration:* a function, declared as a separate statement, in the main code flow. +Erstens, die Syntax, wie man sie im Code unterscheidet +- *Function Declaration*: eine Funktion, die separat deklariert wird. ```js // Function Declaration function sum(a, b) { return a + b; } ``` -- *Function Expression:* a function, created inside an expression or inside another syntax construct. Here, the function is created at the right side of the "assignment expression" `=`: - +- *Function Expression:* eine Funktion die in einem Ausdruck oder einem anderen Konstrukt erstellt wird. Hier wird die Funktion auf der rechten Seite der "Zuweisung" `=` definiert: ```js // Function Expression let sum = function(a, b) { @@ -191,23 +183,23 @@ First, the syntax: how to differentiate between them in the code. }; ``` -The more subtle difference is *when* a function is created by the JavaScript engine. +Der unauffälligere Unterschied ist, *wann* eine Funktion von der JavaScript Engine definiert wird. -**A Function Expression is created when the execution reaches it and is usable only from that moment.** +**Eine Function Expression wird erst erstellt, wenn die Ausführung des Skrpts dort ankommt und ist erst ab dort verwendbar** -Once the execution flow passes to the right side of the assignment `let sum = function…` -- here we go, the function is created and can be used (assigned, called, etc. ) from now on. +Erst wenn die rechte Seite von `let sum = function…` von der Engine erreicht wurde ist die Funktion verfügbar und kann zugewiesen oder ausgeführt werden. -Function Declarations are different. +Function Declarations sind anders. -**A Function Declaration can be called earlier than it is defined.** +**Eine Function Declaration kann verwendet werden, bevor sie definiert wurde** -For example, a global Function Declaration is visible in the whole script, no matter where it is. +Z.B. eine globale Function Declaration ist im ganzen Skript sichtbar, egal, in welcher Zeile sie steht. -That's due to internal algorithms. When JavaScript prepares to run the script, it first looks for global Function Declarations in it and creates the functions. We can think of it as an "initialization stage". +Das liegt an internen Algorithmen. Wenn JavaSkript beginnt, ein Skript auszuführen, dann sucht es zunächst, globale Function Declarations im Skript und erstellt die Funktionen. Wir können uns das als die "Aufwärmphase" vorstellen. -And after all Function Declarations are processed, the code is executed. So it has access to these functions. +Nachdem alle Function Declarations verarbeitet wurden erst, wird der Code ausgeführt. Daher hat er schon Zugang zu den Funktionen. -For example, this works: +Das hier funktioniert: ```js run refresh untrusted *!* @@ -219,34 +211,34 @@ function sayHi(name) { } ``` -The Function Declaration `sayHi` is created when JavaScript is preparing to start the script and is visible everywhere in it. +Die Function Declaration `sayHi` wird schon in der Aufwärmphase erstellt und daher überall verfügbar. -...If it were a Function Expression, then it wouldn't work: +...Wenn es eine Function Expression wäre, dann würde es nicht funktionieren: ```js run refresh untrusted *!* sayHi("John"); // error! */!* -let sayHi = function(name) { // (*) no magic any more +let sayHi = function(name) { // (*) kaputt... alert( `Hello, ${name}` ); }; ``` -Function Expressions are created when the execution reaches them. That would happen only in the line `(*)`. Too late. +Funktionsausdrücke werden erst erstellt, wenn sie ausgeführt wurden. Dass passiert erst in Zeile `(*)`, wo es zu spät ist. -Another special feature of Function Declarations is their block scope. +Noch eine Spezialität von Function Declarations ist ihre Sichtbarkeit im Block. -**In strict mode, when a Function Declaration is within a code block, it's visible everywhere inside that block. But not outside of it.** +**Im modernen "strict mode" ist eine Function Declaration - falls in einem Block stehend - nur in dem Block auch sichtbar. Außerhalb nicht. -For instance, let's imagine that we need to declare a function `welcome()` depending on the `age` variable that we get during runtime. And then we plan to use it some time later. +Stellen wir uns beispielsweise vor, wir bräuchten eine Funktion `welcome()`, die von der variable `age` abhängt, deren Wert während der Skriptausführung bestimmt wird. -If we use Function Declaration, it won't work as intended: +Per Function Declaration funktioniert es nicht wie gewünscht. ```js run let age = prompt("What is your age?", 18); -// conditionally declare a function +// eine Funktion konditionell definieren if (age < 18) { function welcome() { @@ -261,30 +253,30 @@ if (age < 18) { } -// ...use it later +// ...und später nutzen *!* -welcome(); // Error: welcome is not defined +welcome(); // Error: welcome ist undefiniert. */!* ``` -That's because a Function Declaration is only visible inside the code block in which it resides. +Das liegt daran, dass Function Declarations nur innerhalb von ihrem Codeblock verfügbar sind -Here's another example: +Ein weiteres Beispiel: ```js run let age = 16; // take 16 as an example if (age < 18) { *!* - welcome(); // \ (runs) + welcome(); // \ (führt aus) */!* // | function welcome() { // | - alert("Hello!"); // | Function Declaration is available - } // | everywhere in the block where it's declared + alert("Hello!"); // | function declaration ist überall in dem + } // | Block, in dem sie deklariert wird // | *!* - welcome(); // / (runs) + welcome(); // / (fhrt aus) */!* } else { @@ -294,19 +286,19 @@ if (age < 18) { } } -// Here we're out of curly braces, -// so we can not see Function Declarations made inside of them. +// Hier sind wir außerhalb der geschwungenen Klammern, +// daher können wir die Function Declarations, die innerhalb geschehen, nicht sehen. *!* -welcome(); // Error: welcome is not defined +welcome(); // Error: welcome ist nicht definiert. */!* ``` -What can we do to make `welcome` visible outside of `if`? +Wie machen wir `welcome` außerhalb von `if` sichtbar? -The correct approach would be to use a Function Expression and assign `welcome` to the variable that is declared outside of `if` and has the proper visibility. +Korrekt wäre es, eine Function Expression zu verwenden und `welcome` der Variable zuzuweisen, die wir außerhalb des Blocks definiert haben, sodass sie überall sichtbar ist. -This code works as intended: +Das hier funktioniert: ```js run let age = prompt("What is your age?", 18); @@ -333,6 +325,7 @@ welcome(); // ok now ``` Or we could simplify it even further using a question mark operator `?`: +Noch einfacher können wir es mit dem Fragezeichenoperator `?` schreiben: ```js run let age = prompt("What is your age?", 18); @@ -342,27 +335,27 @@ let welcome = (age < 18) ? function() { alert("Greetings!"); }; *!* -welcome(); // ok now +welcome(); // jetzt geht's */!* ``` -```smart header="When to choose Function Declaration versus Function Expression?" -As a rule of thumb, when we need to declare a function, the first to consider is Function Declaration syntax. It gives more freedom in how to organize our code, because we can call such functions before they are declared. +```smart header="Wann sollte man eine Function Declaration, wann einen Ausdruck verwenden?" +Als Daumenregel ist die Syntakx Function Declaration die erste Wahl. Sie gibt einem mehr Freiheit in der Organisation des Code, denn wir können sie aufrufen, bevor sie definiert wurde. -That's also better for readability, as it's easier to look up `function f(…) {…}` in the code than `let f = function(…) {…};`. Function Declarations are more "eye-catching". +Dies hilft auch der Lesbarkeit, denn es ist leichter, nach `function f(…) {…}` im Code zu suchen, als nach `let f = function(…) {…};`. function declarations "springen ins Auge". -...But if a Function Declaration does not suit us for some reason, or we need a conditional declaration (we've just seen an example), then Function Expression should be used. +Aber manchmal benötigen wir eine bedingte Definition (wie eben im Beispiel) oder haben andere Gründe eine Function Expression zu bevorzugen. ``` -## Summary +## Zusammenfassung -- Functions are values. They can be assigned, copied or declared in any place of the code. -- If the function is declared as a separate statement in the main code flow, that's called a "Function Declaration". -- If the function is created as a part of an expression, it's called a "Function Expression". -- Function Declarations are processed before the code block is executed. They are visible everywhere in the block. -- Function Expressions are created when the execution flow reaches them. +- Funktionen sind Werte. Sie können überall im Code zugewiesen, kopiert oder deklariert werden. +- Wenn die Funktion in einem extra Statement im Hauptcode deklariert wird, dann nennt man das "Function Declaration". +- Wenn sie als Teil eines Ausdrucks definiert wird, nennen wir das "function expression". +- Function Declarations werden verarbeitet bevor der Block ausgeführt wird. Sie sind im ganzen Block sichtbar. +- Function Expressions werden erst erstellt, wenn der Ausführungsfluss sie erreicht. -In most cases when we need to declare a function, a Function Declaration is preferable, because it is visible prior to the declaration itself. That gives us more flexibility in code organization, and is usually more readable. +Meistens, wenn wir eine Funktion definieren, sollten wir eine Function Declaration nutzen, da sie überall sichtbar ist. Das sorgt für flexiblere Codeorganisation und bessere Lesbarkeit. -So we should use a Function Expression only when a Function Declaration is not fit for the task. We've seen a couple of examples of that in this chapter, and will see more in the future. +Daher sollten wir einen Function Expression nur verwenden, wenn die Function Declaration ungeeignet ist. Dazu haben wir einige Beispiele behandelt und werden in Zukunft noch mehr kennenlernen.