Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Object methods, "this" #42

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
**Error**!

Try it:
Man versuche es einfach:

```js run
let user = {
Expand All @@ -11,19 +11,19 @@ let user = {
(user.go)() // error!
```

The error message in most browsers does not give us much of a clue about what went wrong.
Die Fehlermedlung in den meisten Browsern liefert einen nicht wirklich ein Verständnis dafür was schief lief.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Die Fehlermeldung in den meisten Browsern liefert einem nicht wirklich ein Verständnis dafür, was schief lief.


**The error appears because a semicolon is missing after `user = {...}`.**
**Der Fehler erscheint, da ein Semikolon nach `user = {...}` fehlt.**

JavaScript does not auto-insert a semicolon before a bracket `(user.go)()`, so it reads the code like:
JavaScript fügt automatisch kein Semikolon vor einer Klammer ein, weshalb das Skript den Code wie folgt liest:

```js no-beautify
let user = { go:... }(user.go)()
```

Then we can also see that such a joint expression is syntactically a call of the object `{ go: ... }` as a function with the argument `(user.go)`. And that also happens on the same line with `let user`, so the `user` object has not yet even been defined, hence the error.
Wir können zudem sehen, das solch eine zusammenhängende Expression syntakitisch gesehen der Aufruf des Objekt `{ go: ... }` ist, als eine Funktion mit dem Argument `(user.go)`. Und genau das passiert in der selben Zeile mit `let user`, sodass das Objekt `user` nicht einmal definiert wurde. Darum der Fehler.

If we insert the semicolon, all is fine:
Wenn wir ein Semikolon einfügen läuft alles wie gewollt:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wenn wir ein Semikolon einfügen, läuft alles wie gewollt:


```js run
let user = {
Expand All @@ -34,4 +34,4 @@ let user = {
(user.go)() // John
```

Please note that parentheses around `(user.go)` do nothing here. Usually they setup the order of operations, but here the dot `.` works first anyway, so there's no effect. Only the semicolon thing matters.
Man beachte, dass die Parenthesen um `(user.go)` nichts bewirken. Normalerweise stellen sie die Reihenfolge der Operationen auf, aber hier agiert der Punkt `.` zuerst, weshalb sie keine Wirkung haben. Nur die Sache mit dem Semikolon zählt.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Man beachte, dass die Klammern um (user.go) nichts bewirken.

Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ importance: 2

---

# Syntax check
# Syntaxprüfung

What is the result of this code?
Was ist das Resultat des folgenden Code?


```js no-beautify
Expand All @@ -16,4 +16,4 @@ let user = {
(user.go)()
```

P.S. There's a pitfall :)
P.S. Es gibt eine Falle :)
16 changes: 8 additions & 8 deletions 1-js/04-object-basics/04-object-methods/3-why-this/solution.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@

Here's the explanations.
Hier sind die Erklärungen.

1. That's a regular object method call.
1. Das ist ein regulärer Aufruf der dem Objekt zugehörigen Methode.

2. The same, parentheses do not change the order of operations here, the dot is first anyway.
2. Das selbe, da Parenthesen hier nicht die Reihenfolge der Operationen beeinflusst. Der Punkt steht trotzdem davor.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Das selbe, da Klammern hier nicht die Reihenfolge der Operationen beeinflussen.


3. Here we have a more complex call `(expression).method()`. The call works as if it were split into two lines:
3. Hier haben wir den komplexeren Aufruf `(expression).method()`. Der Aufruf funktioniert so, als wäre er in zwei Zeilen unterteilt worden:

```js no-beautify
f = obj.go; // calculate the expression
f(); // call what we have
```

Here `f()` is executed as a function, without `this`.
Hier wird `f()` als eine Funktion ohne `this` ausgeführt.

4. The similar thing as `(3)`, to the left of the dot `.` we have an expression.
5. Die ähnliche Sachw wie bei `(3)`. Zur linken des `.` steht eine Expression.
CourageSean marked this conversation as resolved.
Show resolved Hide resolved

To explain the behavior of `(3)` and `(4)` we need to recall that property accessors (dot or square brackets) return a value of the Reference Type.
Um das Verhalten von `(3)` und `(4)` zu versthen müseen wir uns daran erinnern, dass die Zurgiffe auf Properties (Punkt oder eckige Klammern) einen Wert des Peferenztyp wiedergeben.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Um das Verhalten von (3) und (4) zu verstehen, müssen wir uns daran erinnern, dass die Zugriffe auf Properties (Punkt oder eckige Klammern) einen Wert des Referenztyp wiedergeben.


Any operation on it except a method call (like assignment `=` or `||`) turns it into an ordinary value, which does not carry the information allowing to set `this`.
Jegliche Operation die auf ihnen ausgeführt wird, mit Ausnahme eines Aufruf einer Methode (wie Zuweisungt `=` oder `||`), wandelt deren Wert in einen gewöhnlichen Wert um, der die nötige Inforamtion um ein `this` zu benutzen nicht aufnimmt.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(wie Zuweisung = oder ||), wandelt deren Wert in einen gewöhnlichen Wert um, der die nötige Information um ein this zu benutzen, nicht aufnimmt.


7 changes: 3 additions & 4 deletions 1-js/04-object-basics/04-object-methods/3-why-this/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 3

---

# Explain the value of "this"
# Man erkläre die Werte von "this"

In the code below we intend to call `obj.go()` method 4 times in a row.
Im unten stehenden Code wollen wir die Methode `obj.go()` vier mal hintereinander aufrufen.

But calls `(1)` and `(2)` works differently from `(3)` and `(4)`. Why?
Aber die Aufrufe `(1)` und `(2)`funktionieren ander als die von `(3)` und `(4)`. Warum?
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anders


```js run no-beautify
let obj, method;
Expand All @@ -23,4 +23,3 @@ obj.go(); // (1) [object Object]

(obj.go || obj.stop)(); // (4) undefined
```

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
**Answer: an error.**
**Die Antwort: Ein Fehler.**

Try it:
Man soll es einfach mal versuchen:
```js run
function makeUser() {
return {
Expand All @@ -11,29 +11,29 @@ function makeUser() {

let user = makeUser();

alert( user.ref.name ); // Error: Cannot read property 'name' of undefined
alert( user.ref.name ); // Fehler: Cannot read property 'name' of undefined
```

That's because rules that set `this` do not look at object definition. Only the moment of call matters.
Das liegt an den Regeln die `this` festlegen: Sie schauen nicht nach der Definition eines Objekt. Nur der Zeipunkt des Aufruf spielt eine Rolle.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sie schauen nicht auf die Definition eines Objektes. Nur der Zeitpunkt des Aufrufs spielt eine Rolle


Here the value of `this` inside `makeUser()` is `undefined`, because it is called as a function, not as a method with "dot" syntax.
Hier ist der Wert von `this` innerhlab von `makeUser()` `undefined`, da dieser als Funbktion aufgerufen wird und nicht als eine Methode mit dem "Punktsyntax".
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

da dieser als Funktion aufgerufen wird und nicht als eine Methode mit der "Punktsyntax".


The value of `this` is one for the whole function, code blocks and object literals do not affect it.
Der Wert von `this` ist einer für die ganze Funktion. Code Blocks und literale Objekte haben keinen Einfluss darauf.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Der Wert von this ist derselbe für die ganze Funktion.


So `ref: this` actually takes current `this` of the function.
Deshalb nimmt sich `ref: this` das aktuelle `this` der Funktion.

We can rewrite the function and return the same `this` with `undefined` value:
Wir koennen die Funktion umschreiben und das selbe `this` mit dem Wert `undefined` ausgeben:

```js run
function makeUser(){
return this; // this time there's no object literal
return this; // dieses Mal gibt es kein literales Objekt
}

alert( makeUser().name ); // Error: Cannot read property 'name' of undefined
alert( makeUser().name ); // Fehler: Property 'name' von undefined kann nicht gelesen werden
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fehler nicht übersetzen - code snippet

```
As you can see the result of `alert( makeUser().name )` is the same as the result of `alert( user.ref.name )` from the previous example.
Wie man sehen kann ist das Resultat von `alert( makeUser().name )` das selbe wie von `alert( user.ref.name )` im obigen Beispiel.

Here's the opposite case:
Hier der umgekehrte Fall:

```js run
function makeUser() {
Expand All @@ -52,4 +52,4 @@ let user = makeUser();
alert( user.ref().name ); // John
```

Now it works, because `user.ref()` is a method. And the value of `this` is set to the object before dot `.`.
Jetzt funktioner es, da `user.ref()` eine Methode ist. Und der Wert von `this` wurde zu dem Objekt vor dem Punkt '.'.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jetzt funktioniert es

Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Using "this" in object literal
# Der Gebrauch von "this" bei literalen Objekten

Here the function `makeUser` returns an object.
Hier gibt die Funktion `makeUser` ein Objekt aus.

What is the result of accessing its `ref`? Why?
Was ist das Resultat wenn man auf dessen `ref` zugreift und weshalb?
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was ist das Resultat, wenn man auf dessen


```js
function makeUser() {
Expand All @@ -18,6 +18,6 @@ function makeUser() {

let user = makeUser();

alert( user.ref.name ); // What's the result?
alert( user.ref.name ); // Was ist das Resultat?
```

12 changes: 6 additions & 6 deletions 1-js/04-object-basics/04-object-methods/7-calculator/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ importance: 5

---

# Create a calculator
# Einen Rechner erstellen

Create an object `calculator` with three methods:
Die Aufgabe ist es ein Objekt `calculator` mit drei Methoden zu erstellen:
CourageSean marked this conversation as resolved.
Show resolved Hide resolved

- `read()` prompts for two values and saves them as object properties.
- `sum()` returns the sum of saved values.
- `mul()` multiplies saved values and returns the result.
- `read()` fordert einen auf zwei Werte anzugeben, die diese als Properties des Objekt abscpeichert.
CourageSean marked this conversation as resolved.
Show resolved Hide resolved
- `sum()` gibt die Summer der zwei abgespeicherten Werte an.
CourageSean marked this conversation as resolved.
Show resolved Hide resolved
- `mul()` multipliziert die abgespeicherten Werte miteinander und gibt das Resultat aus.

```js
let calculator = {
// ... your code ...
// ... code ...
};

calculator.read();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The solution is to return the object itself from every call.
Die Lösung liegt darin, das Objekt selbst bei jedem Aufruf auszugeben.

```js run demo
let ladder = {
Expand Down Expand Up @@ -26,7 +26,7 @@ let ladder = {
ladder.up().up().down().up().down().showStep(); // 1
```

We also can write a single call per line. For long chains it's more readable:
Wir können auch einen Aufruf per Zeile schreiben. Bei längeren Ketten ist das besser lesbar:
CourageSean marked this conversation as resolved.
Show resolved Hide resolved

```js
ladder
Expand Down
12 changes: 6 additions & 6 deletions 1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ importance: 2

---

# Chaining
# Verketten

There's a `ladder` object that allows to go up and down:
Es gibt ein Objekt `ladder`, dass es erlaubt auf un ab zu gehen:
CourageSean marked this conversation as resolved.
Show resolved Hide resolved

```js
let ladder = {
Expand All @@ -15,13 +15,13 @@ let ladder = {
down() {
this.step--;
},
showStep: function() { // shows the current step
showStep: function() { // zeigt die derzeitige Stufe an
alert( this.step );
}
};
```

Now, if we need to make several calls in sequence, can do it like this:
Wenn wir nun mehrere Aufrufe hintereinander möchten, können wir das wie folgt tun:

```js
ladder.up();
Expand All @@ -30,10 +30,10 @@ ladder.down();
ladder.showStep(); // 1
```

Modify the code of `up`, `down` and `showStep` to make the calls chainable, like this:
Man modifiziere den Code von `up`, `down` und `showStep` so, dass man die Aufrufe wie folgt verketten kann:

```js
ladder.up().up().down().showStep(); // 1
```

Such approach is widely used across JavaScript libraries.
Solch eine Herangehensweise ist bei JavaScript Libraries weit verbreitet.
Loading