From 4bffc81422ebfa19c2744f13a5490a9ab568f40a Mon Sep 17 00:00:00 2001 From: otmon76 <66325539+otmon76@users.noreply.github.com> Date: Thu, 16 Jan 2025 22:06:35 +0100 Subject: [PATCH] Revert "Object methods, "this"" --- .../4-object-property-this/solution.md | 46 ++-- .../4-object-property-this/task.md | 16 +- .../7-calculator/_js.view/solution.js | 8 +- .../7-calculator/_js.view/test.js | 21 +- .../7-calculator/solution.md | 14 +- .../04-object-methods/7-calculator/task.md | 20 +- .../8-chain-calls/_js.view/solution.js | 17 +- .../8-chain-calls/_js.view/test.js | 30 +-- .../8-chain-calls/solution.md | 36 +-- .../04-object-methods/8-chain-calls/task.md | 40 +-- .../04-object-methods/article.md | 250 +++++++++--------- 11 files changed, 247 insertions(+), 251 deletions(-) diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md index d40185f5b..f33c9310e 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md @@ -1,55 +1,55 @@ -**Odpověď: chyba.** +**Answer: an error.** -Zkuste to: +Try it: ```js run -function vytvořUživatele() { +function makeUser() { return { - jméno: "Jan", - odkaz: this + name: "John", + ref: this }; } -let uživatel = vytvořUživatele(); +let user = makeUser(); -alert( uživatel.odkaz.jméno ); // Chyba: Nelze načíst vlastnost 'jméno' objektu undefined +alert( user.ref.name ); // Error: Cannot read property 'name' of undefined ``` -Je to proto, že pravidla, která nastavují `this`, se nedívají do definice objektu. Záleží jen na okamžiku volání. +That's because rules that set `this` do not look at object definition. Only the moment of call matters. -Zde je hodnota `this` uvnitř `vytvořUživatele()` `undefined`, protože tato funkce je volána jako funkce, ne jako metoda „tečkovou“ syntaxí. +Here the value of `this` inside `makeUser()` is `undefined`, because it is called as a function, not as a method with "dot" syntax. -Hodnota `this` je stejná pro celou funkci, bloky kódu a objektové literály ji neovlivňují. +The value of `this` is one for the whole function, code blocks and object literals do not affect it. -Takže `odkaz: this` vezme ve skutečnosti aktuální `this` této funkce. +So `ref: this` actually takes current `this` of the function. -Můžeme funkci přepsat a vrátit stejné `this` s hodnotou `undefined`: +We can rewrite the function and return the same `this` with `undefined` value: ```js run -function vytvořUživatele(){ - return this; // tentokrát tady není objektový literál +function makeUser(){ + return this; // this time there's no object literal } -alert( vytvořUživatele().jméno ); // Chyba: Nelze načíst vlastnost 'jméno' objektu undefined +alert( makeUser().name ); // Error: Cannot read property 'name' of undefined ``` -Jak vidíte, výsledek `alert( vytvořUživatele().jméno )` je stejný jako výsledek `alert( uživatel.odkaz.jméno )` z předchozího příkladu. +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. -Toto je opačný příklad: +Here's the opposite case: ```js run -function vytvořUživatele() { +function makeUser() { return { - jméno: "Jan", + name: "John", *!* - odkaz() { + ref() { return this; } */!* }; } -let uživatel = vytvořUživatele(); +let user = makeUser(); -alert( uživatel.odkaz().jméno ); // Jan +alert( user.ref().name ); // John ``` -Teď to funguje, protože `uživatel.odkaz()` je metoda. A hodnota `this` se nastaví na objekt před tečkou `.`. \ No newline at end of file +Now it works, because `user.ref()` is a method. And the value of `this` is set to the object before dot `.`. diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md index 20bdcde72..c6f8f9658 100644 --- a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md +++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md @@ -2,22 +2,22 @@ importance: 5 --- -# Použití „this“ v objektovém literálu +# Using "this" in object literal -Zde funkce `vytvořUživatele` vrátí objekt. +Here the function `makeUser` returns an object. -Jaký je výsledek přístupu k jeho vlastnosti `odkaz`? Proč? +What is the result of accessing its `ref`? Why? ```js -function vytvořUživatele() { +function makeUser() { return { - jméno: "Jan", - odkaz: this + name: "John", + ref: this }; } -let uživatel = vytvořUživatele(); +let user = makeUser(); -alert( uživatel.odkaz.jméno ); // Jaký je výsledek? +alert( user.ref.name ); // What's the result? ``` diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/solution.js b/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/solution.js index 892c060a4..9ccbe43a1 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/solution.js +++ b/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/solution.js @@ -1,13 +1,13 @@ -let kalkulátor = { - součet() { +let calculator = { + sum() { return this.a + this.b; }, - součin() { + mul() { return this.a * this.b; }, - načti() { + read() { this.a = +prompt('a?', 0); this.b = +prompt('b?', 0); } diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js b/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js index e5c76fe2b..4decb76dc 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js +++ b/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js @@ -1,31 +1,32 @@ -describe("kalkulátor", function() { + +describe("calculator", function() { - context("když zadáme 2 a 3", function() { + context("when 2 and 3 entered", function() { beforeEach(function() { sinon.stub(window, "prompt"); prompt.onCall(0).returns("2"); prompt.onCall(1).returns("3"); - kalkulátor.načti(); + calculator.read(); }); afterEach(function() { prompt.restore(); }); - it('funkce načti načte dvě hodnoty a uloží je jako vlastnosti objektu', function () { - assert.equal(kalkulátor.a, 2); - assert.equal(kalkulátor.b, 3); + it('the read get two values and saves them as object properties', function () { + assert.equal(calculator.a, 2); + assert.equal(calculator.b, 3); }); - it("součet je 5", function() { - assert.equal(kalkulátor.součet(), 5); + it("the sum is 5", function() { + assert.equal(calculator.sum(), 5); }); - it("součin je 6", function() { - assert.equal(kalkulátor.součin(), 6); + it("the multiplication product is 6", function() { + assert.equal(calculator.mul(), 6); }); }); diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/solution.md b/1-js/04-object-basics/04-object-methods/7-calculator/solution.md index 0925287b8..459997624 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/solution.md +++ b/1-js/04-object-basics/04-object-methods/7-calculator/solution.md @@ -1,21 +1,21 @@ ```js run demo solution -let kalkulátor = { - součet() { +let calculator = { + sum() { return this.a + this.b; }, - součin() { + mul() { return this.a * this.b; }, - načti() { + read() { this.a = +prompt('a?', 0); this.b = +prompt('b?', 0); } }; -kalkulátor.načti(); -alert( kalkulátor.součet() ); -alert( kalkulátor.součin() ); +calculator.read(); +alert( calculator.sum() ); +alert( calculator.mul() ); ``` diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/task.md b/1-js/04-object-basics/04-object-methods/7-calculator/task.md index b6b51a1b4..82d0da030 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/task.md +++ b/1-js/04-object-basics/04-object-methods/7-calculator/task.md @@ -2,22 +2,22 @@ importance: 5 --- -# Vytvořte kalkulátor +# Create a calculator -Vytvořte objekt `kalkulátor` se třemi metodami: +Create an object `calculator` with three methods: -- `načti()` se zeptá na dvě hodnoty a uloží je jako vlastnosti objektu pod názvy po řadě `a` a `b`. -- `součet()` vrátí součet uložených hodnot. -- `součin()` vynásobí uložené hodnoty mezi sebou a vrátí výsledek. +- `read()` prompts for two values and saves them as object properties with names `a` and `b` respectively. +- `sum()` returns the sum of saved values. +- `mul()` multiplies saved values and returns the result. ```js -let kalkulátor = { - // ... váš kód ... +let calculator = { + // ... your code ... }; -kalkulátor.načti(); -alert( kalkulátor.součet() ); -alert( kalkulátor.součin() ); +calculator.read(); +alert( calculator.sum() ); +alert( calculator.mul() ); ``` [demo] diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js index 577cda7d8..a35c009cc 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js @@ -1,21 +1,16 @@ -let žebřík = { - stupeň: 0, - nahoru: function() { - this.stupeň++; +let ladder = { + step: 0, + up: function() { + this.step++; return this; }, - dolů: function() { - this.stupeň--; + down: function() { + this.step--; return this; }, -<<<<<<< HEAD - zobrazStupeň: function() { - alert(this.stupeň); -======= showStep: function() { alert(this.step); return this; ->>>>>>> 71da17e5960f1c76aad0d04d21f10bc65318d3f6 } }; \ No newline at end of file diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js index b6e514e0f..b4f2459b7 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js @@ -1,36 +1,36 @@ -describe('Žebřík', function() { +describe('Ladder', function() { before(function() { window.alert = sinon.stub(window, "alert"); }); beforeEach(function() { - žebřík.stupeň = 0; + ladder.step = 0; }); - it('nahoru() by mělo vrátit this', function() { - assert.equal(žebřík.nahoru(), žebřík); + it('up() should return this', function() { + assert.equal(ladder.up(), ladder); }); - it('dolů() by mělo vrátit this', function() { - assert.equal(žebřík.dolů(), žebřík); + it('down() should return this', function() { + assert.equal(ladder.down(), ladder); }); - it('zobrazStupeň() by mělo volat alert', function() { - žebřík.zobrazStupeň(); + it('showStep() should call alert', function() { + ladder.showStep(); assert(alert.called); }); - it('nahoru() by mělo zvýšit stupeň', function() { - assert.equal(žebřík.nahoru().nahoru().stupeň, 2); + it('up() should increase step', function() { + assert.equal(ladder.up().up().step, 2); }); - it('dolů() by mělo snížit stupeň', function() { - assert.equal(žebřík.dolů().stupeň, -1); + it('down() should decrease step', function() { + assert.equal(ladder.down().step, -1); }); - it('dolů().nahoru().nahoru().nahoru() ', function() { - assert.equal(žebřík.dolů().nahoru().nahoru().nahoru().stupeň, 2); + it('down().up().up().up() ', function() { + assert.equal(ladder.down().up().up().up().step, 2); }); it('showStep() should return this', function() { @@ -42,7 +42,7 @@ describe('Žebřík', function() { }); after(function() { - žebřík.stupeň = 0; + ladder.step = 0; alert.restore(); }); }); diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md index 1e7ee3170..f215461dd 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md @@ -1,39 +1,39 @@ -Řešením je v každém volání vrátit tento objekt samotný. +The solution is to return the object itself from every call. ```js run demo -let žebřík = { - stupeň: 0, - nahoru() { - this.stupeň++; +let ladder = { + step: 0, + up() { + this.step++; *!* return this; */!* }, - dolů() { - this.stupeň--; + down() { + this.step--; *!* return this; */!* }, - zobrazStupeň() { - alert( this.stupeň ); + showStep() { + alert( this.step ); *!* return this; */!* } }; -žebřík.nahoru().nahoru().dolů().zobrazStupeň().dolů().zobrazStupeň(); // zobrazí 1, pak 0 +ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0 ``` -Můžeme také psát každé volání na nový řádek. U delšího zřetězení je to čitelnější: +We also can write a single call per line. For long chains it's more readable: ```js -žebřík - .nahoru() - .nahoru() - .dolů() - .zobrazStupeň() // 1 - .dolů() - .zobrazStupeň(); // 0 +ladder + .up() + .up() + .down() + .showStep() // 1 + .down() + .showStep(); // 0 ``` diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md index 6056342f4..7d2ef8c15 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md @@ -2,40 +2,40 @@ importance: 2 --- -# Zřetězení +# Chaining -Máme objekt `žebřík`, který nám umožňuje chodit nahoru a dolů: +There's a `ladder` object that allows you to go up and down: ```js -let žebřík = { - stupeň: 0, - nahoru() { - this.stupeň++; +let ladder = { + step: 0, + up() { + this.step++; }, - dolů() { - this.stupeň--; + down() { + this.step--; }, - zobrazStupeň: function() { // zobrazí aktuální stupeň - alert( this.stupeň ); + showStep: function() { // shows the current step + alert( this.step ); } }; ``` -Když nyní potřebujeme učinit několik volání po sobě, můžeme to udělat takto: +Now, if we need to make several calls in sequence, we can do it like this: ```js -žebřík.nahoru(); -žebřík.nahoru(); -žebřík.dolů(); -žebřík.zobrazStupeň(); // 1 -žebřík.dolů(); -žebřík.zobrazStupeň(); // 0 +ladder.up(); +ladder.up(); +ladder.down(); +ladder.showStep(); // 1 +ladder.down(); +ladder.showStep(); // 0 ``` -Upravte kód funkcí `nahoru`, `dolů` a `zobrazStupeň` tak, aby bylo možné volání zřetězit takto: +Modify the code of `up`, `down`, and `showStep` to make the calls chainable, like this: ```js -žebřík.nahoru().nahoru().dolů().zobrazStupeň().dolů().zobrazStupeň(); // zobrazí 1, pak 0 +ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0 ``` -Takový přístup se zeširoka používá v JavaScriptových knihovnách. +Such an approach is widely used across JavaScript libraries. diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md index 7effbc17b..cea2b6a70 100644 --- a/1-js/04-object-basics/04-object-methods/article.md +++ b/1-js/04-object-basics/04-object-methods/article.md @@ -1,270 +1,270 @@ -# Objektové metody, „this“ +# Object methods, "this" -Objekty se obvykle vytvářejí tak, aby představovaly entity ze skutečného světa, například uživatele, objednávky a podobně: +Objects are usually created to represent entities of the real world, like users, orders and so on: ```js -let uživatel = { - jméno: "Jan", - věk: 30 +let user = { + name: "John", + age: 30 }; ``` -A ve skutečném světě může uživatel *konat* nějakou akci: vybrat si něco z nákupního vozíku, přihlásit se, odhlásit se atd. +And, in the real world, a user can *act*: select something from the shopping cart, login, logout etc. -V JavaScriptu jsou tyto akce reprezentovány funkcemi ve vlastnostech. +Actions are represented in JavaScript by functions in properties. -## Příklady metod +## Method examples -Pro začátek naučme objekt `uživatel` říci ahoj: +For a start, let's teach the `user` to say hello: ```js run -let uživatel = { - jméno: "Jan", - věk: 30 +let user = { + name: "John", + age: 30 }; *!* -uživatel.řekniAhoj = function() { - alert("Ahoj!"); +user.sayHi = function() { + alert("Hello!"); }; */!* -uživatel.řekniAhoj(); // Ahoj! +user.sayHi(); // Hello! ``` -Právě jsme použili funkční výraz, kterým jsme vytvořili funkci a přiřadili ji do vlastnosti objektu `uživatel.řekniAhoj`. +Here we've just used a Function Expression to create a function and assign it to the property `user.sayHi` of the object. -Pak ji můžeme volat pomocí `uživatel.řekniAhoj()`. Uživatel nyní umí mluvit! +Then we can call it as `user.sayHi()`. The user can now speak! -Funkce, která je vlastností objektu, se nazývá jeho *metoda*. +A function that is a property of an object is called its *method*. -Zde tedy máme metodu `řekniAhoj` objektu `uživatel`. +So, here we've got a method `sayHi` of the object `user`. -Samozřejmě můžeme použít jako metodu předem deklarovanou funkci, například takto: +Of course, we could use a pre-declared function as a method, like this: ```js run -let uživatel = { +let user = { // ... }; *!* -// nejprve ji deklarujeme -function řekniAhoj() { - alert("Ahoj!"); -}; +// first, declare +function sayHi() { + alert("Hello!"); +} -// pak přidáme jako metodu -uživatel.řekniAhoj = řekniAhoj; +// then add as a method +user.sayHi = sayHi; */!* -uživatel.řekniAhoj(); // Ahoj! +user.sayHi(); // Hello! ``` -```smart header="Objektově orientované programování" -Způsob programování, při kterém píšeme kód, který používá objekty představující entity, se nazývá [objektově orientované programování](https://cs.wikipedia.org/wiki/Objektově_orientované_programování), zkráceně „OOP“. +```smart header="Object-oriented programming" +When we write our code using objects to represent entities, that's called [object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming), in short: "OOP". -OOP je velká věc a samo o sobě je zajímavou vědou. Jak zvolit správné entity? Jak zorganizovat interakci mezi nimi? To je architektura a o tomto tématu existují skvělé knihy, např. „Design Patterns: Elements of Reusable Object-Oriented Software“ od E. Gammy, R. Helma, R. Johnsona a J. Vissidese, nebo „Object-Oriented Analysis and Design with Applications“ od G. Booche a další. +OOP is a big thing, an interesting science of its own. How to choose the right entities? How to organize the interaction between them? That's architecture, and there are great books on that topic, like "Design Patterns: Elements of Reusable Object-Oriented Software" by E. Gamma, R. Helm, R. Johnson, J. Vissides or "Object-Oriented Analysis and Design with Applications" by G. Booch, and more. ``` -### Zkratky metod +### Method shorthand -V objektovém literálu existuje i kratší syntaxe metod: +There exists a shorter syntax for methods in an object literal: ```js -// tyto objekty dělají totéž +// these objects do the same -uživatel = { - řekniAhoj: function() { - alert("Ahoj"); +user = { + sayHi: function() { + alert("Hello"); } }; -// zkratka metody vypadá lépe, že? -uživatel = { +// method shorthand looks better, right? +user = { *!* - řekniAhoj() { // totéž jako „řekniAhoj: function(){...}“ + sayHi() { // same as "sayHi: function(){...}" */!* - alert("Ahoj"); + alert("Hello"); } }; ``` -Jak vidíme, můžeme vypustit slovo `"function"` a napsat jen `řekniAhoj()`. +As demonstrated, we can omit `"function"` and just write `sayHi()`. -Upřímně řečeno, tyto notace nejsou zcela identické. Jsou v nich drobné rozdíly týkající se objektové dědičnosti (která bude vysvětlena později), ale na nich nám prozatím nezáleží. Téměř ve všech případech se dává přednost kratší syntaxi. +To tell the truth, the notations are not fully identical. There are subtle differences related to object inheritance (to be covered later), but for now they do not matter. In almost all cases, the shorter syntax is preferred. -## „this“ v metodách +## "this" in methods -Běžně se stává, že objektová metoda potřebuje přístup k informaci uložené v objektu, aby mohla vykonat svou práci. +It's common that an object method needs to access the information stored in the object to do its job. -Například kód uvnitř `uživatel.řekniAhoj()` může potřebovat jméno objektu `uživatel`. +For instance, the code inside `user.sayHi()` may need the name of the `user`. -**K přístupu do objektu může metoda používat klíčové slovo `this`.** +**To access the object, a method can use the `this` keyword.** -Hodnota `this` je objekt „před tečkou“, tedy ten, který byl použit k volání metody. +The value of `this` is the object "before dot", the one used to call the method. -Například: +For instance: ```js run -let uživatel = { - jméno: "Jan", - věk: 30, +let user = { + name: "John", + age: 30, - řekniAhoj() { + sayHi() { *!* - // „this“ je „aktuální objekt“ - alert(this.jméno); + // "this" is the "current object" + alert(this.name); */!* } }; -uživatel.řekniAhoj(); // Jan +user.sayHi(); // John ``` -Zde během výkonu `uživatel.řekniAhoj()` hodnota `this` bude `uživatel`. +Here during the execution of `user.sayHi()`, the value of `this` will be `user`. -Technicky je možné přistupovat k objektu i bez `this` tak, že se na něj odkážeme přes vnější proměnnou: +Technically, it's also possible to access the object without `this`, by referencing it via the outer variable: ```js -let uživatel = { - jméno: "Jan", - věk: 30, +let user = { + name: "John", + age: 30, - řekniAhoj() { + sayHi() { *!* - alert(uživatel.jméno); // „uživatel“ namísto „this“ + alert(user.name); // "user" instead of "this" */!* } }; ``` -...Takový kód je však nespolehlivý. Pokud se rozhodneme zkopírovat objekt `uživatel` do jiné proměnné, např. `správce = uživatel`, a přepsat proměnnou `uživatel` něčím jiným, pak budeme přistupovat k nesprávnému objektu. +...But such code is unreliable. If we decide to copy `user` to another variable, e.g. `admin = user` and overwrite `user` with something else, then it will access the wrong object. -To je ukázáno zde: +That's demonstrated below: ```js run -let uživatel = { - jméno: "Jan", - věk: 30, +let user = { + name: "John", + age: 30, - řekniAhoj() { + sayHi() { *!* - alert( uživatel.jméno ); // povede k chybě + alert( user.name ); // leads to an error */!* } }; -let správce = uživatel; -uživatel = null; // přepíšeme, aby to bylo zřejmé +let admin = user; +user = null; // overwrite to make things obvious *!* -správce.řekniAhoj(); // TypeError: Cannot read property 'jméno' of null +admin.sayHi(); // TypeError: Cannot read property 'name' of null */!* ``` -Kdybychom uvnitř `alert` použili `this.jméno` namísto `uživatel.jméno`, kód by fungoval. +If we used `this.name` instead of `user.name` inside the `alert`, then the code would work. -## „this“ není vázané +## "this" is not bound -V JavaScriptu se klíčové slovo `this` chová jinak než ve většině ostatních programovacích jazyků. Může být použito v libovolné funkci, i když to není metoda objektu. +In JavaScript, keyword `this` behaves unlike most other programming languages. It can be used in any function, even if it's not a method of an object. -V následujícím příkladu není žádná syntaktická chyba: +There's no syntax error in the following example: ```js -function řekniAhoj() { - alert( *!*this*/!*.jméno ); +function sayHi() { + alert( *!*this*/!*.name ); } ``` -Hodnota `this` se vyhodnocuje za běhu skriptu v závislosti na kontextu. +The value of `this` is evaluated during the run-time, depending on the context. -Například zde bude stejná funkce přiřazena dvěma různým objektům a ve voláních bude mít různá „this“: +For instance, here the same function is assigned to two different objects and has different "this" in the calls: ```js run -let uživatel = { jméno: "Jan" }; -let správce = { jméno: "Správce" }; +let user = { name: "John" }; +let admin = { name: "Admin" }; -function řekniAhoj() { - alert( this.jméno ); +function sayHi() { + alert( this.name ); } *!* -// použijeme stejnou funkci ve dvou objektech -uživatel.f = řekniAhoj; -správce.f = řekniAhoj; +// use the same function in two objects +user.f = sayHi; +admin.f = sayHi; */!* -// tato volání mají různá this -// „this“ uvnitř funkce je objekt „před tečkou“ -uživatel.f(); // Jan (this == uživatel) -správce.f(); // Správce (this == správce) +// these calls have different this +// "this" inside the function is the object "before the dot" +user.f(); // John (this == user) +admin.f(); // Admin (this == admin) -správce['f'](); // Správce (k metodě přistupuje tečka nebo hranaté závorky - na tom nezáleží) +admin['f'](); // Admin (dot or square brackets access the method – doesn't matter) ``` -Platí jednoduché pravidlo: je-li volána `obj.f()`, pak `this` během volání `f` je `obj`. Ve výše uvedeném příkladu je to tedy `uživatel` anebo `správce`. +The rule is simple: if `obj.f()` is called, then `this` is `obj` during the call of `f`. So it's either `user` or `admin` in the example above. -````smart header="Volání bez objektu: `this == undefined`" -Můžeme tuto funkci volat dokonce zcela bez objektu: +````smart header="Calling without an object: `this == undefined`" +We can even call the function without an object at all: ```js run -function řekniAhoj() { +function sayHi() { alert(this); } -řekniAhoj(); // undefined +sayHi(); // undefined ``` -Ve striktním režimu je `this` v tomto případě `undefined`. Pokud se pokusíme přistoupit k `this.jméno`, nastane chyba. +In this case `this` is `undefined` in strict mode. If we try to access `this.name`, there will be an error. -V nestriktním režimu bude hodnota `this` v takovém případě *globální objekt* (v prohlížeči `window`, dostaneme se k tomu později v kapitole [](info:global-object)). To je historické chování, které `"use strict"` opravuje. +In non-strict mode the value of `this` in such case will be the *global object* (`window` in a browser, we'll get to it later in the chapter [](info:global-object)). This is a historical behavior that `"use strict"` fixes. -Takové volání je obvykle programovací chyba. Jestliže je `this` uvnitř funkce, očekává se, že funkce bude volána v kontextu objektu. +Usually such call is a programming error. If there's `this` inside a function, it expects to be called in an object context. ```` -```smart header="Důsledky nevázaného `this`" -Pokud přicházíte z jiného programovacího jazyka, pak jste pravděpodobně zvyklí na myšlenku „vázaného `this`“, kdy v metodách definovaných v nějakém objektu `this` vždy odkazuje na tento objekt. +```smart header="The consequences of unbound `this`" +If you come from another programming language, then you are probably used to the idea of a "bound `this`", where methods defined in an object always have `this` referencing that object. -V JavaScriptu je `this` „volné“, jeho hodnota se vypočítává až při volání a není závislá na tom, kde byla metoda deklarována, ale jen na tom, jaký objekt je „před tečkou“. +In JavaScript `this` is "free", its value is evaluated at call-time and does not depend on where the method was declared, but rather on what object is "before the dot". -Koncept vyhodnocování `this` za běhu má své výhody i nevýhody. Na jednu stranu můžeme tutéž funkci použít opakovaně pro různé objekty. Na druhou stranu větší flexibilita vytváří více prostoru pro chyby. +The concept of run-time evaluated `this` has both pluses and minuses. On the one hand, a function can be reused for different objects. On the other hand, the greater flexibility creates more possibilities for mistakes. -Zde nám nepřísluší soudit, zda je toto rozhodnutí návrhářů jazyka dobré nebo špatné. Porozumíme tomu, jak s ním pracovat, jak využít jeho výhody a vyhnout se problémům. +Here our position is not to judge whether this language design decision is good or bad. We'll understand how to work with it, how to get benefits and avoid problems. ``` -## Šipkové funkce nemají „this“ +## Arrow functions have no "this" -Šipkové funkce jsou zvláštní: nemají „své vlastní“ `this`. Pokud se v takové funkci odkážeme na `this`, bude převzato z vnější „normální“ funkce. +Arrow functions are special: they don't have their "own" `this`. If we reference `this` from such a function, it's taken from the outer "normal" function. -Například zde `šipka()` používá `this` z vnější metody `uživatel.řekniAhoj()`: +For instance, here `arrow()` uses `this` from the outer `user.sayHi()` method: ```js run -let uživatel = { - křestníJméno: "Ilja", - řekniAhoj() { - let šipka = () => alert(this.křestníJméno); - šipka(); +let user = { + firstName: "Ilya", + sayHi() { + let arrow = () => alert(this.firstName); + arrow(); } }; -uživatel.řekniAhoj(); // Ilja +user.sayHi(); // Ilya ``` -To je speciální vlastnost šipkových funkcí. Je užitečná, když ve skutečnosti nechceme mít oddělené `this`, ale chceme je převzít z vnějšího kontextu. Později v kapitole prozkoumáme šipkové funkce více do hloubky. +That's a special feature of arrow functions, it's useful when we actually do not want to have a separate `this`, but rather to take it from the outer context. Later in the chapter we'll go more deeply into arrow functions. -## Shrnutí +## Summary -- Funkce uložené ve vlastnostech objektu se nazývají „metody“. -- Metody umožňují objektům „konat akce“, např. `objekt.dělejNěco()`. -- Metody se na tento objekt mohou odkazovat klíčovým slovem `this`. +- Functions that are stored in object properties are called "methods". +- Methods allow objects to "act" like `object.doSomething()`. +- Methods can reference the object as `this`. -Hodnota `this` je definována za běhu skriptu. -- Když je funkce deklarována, může používat `this`, ale toto `this` nemá žádnou hodnotu, dokud není funkce volána. -- Funkce může být kopírována mezi objekty. -- Když je funkce volána „metodovou“ syntaxí `objekt.metoda()`, hodnota `this` během tohoto volání je `objekt`. +The value of `this` is defined at run-time. +- When a function is declared, it may use `this`, but that `this` has no value until the function is called. +- A function can be copied between objects. +- When a function is called in the "method" syntax: `object.method()`, the value of `this` during the call is `object`. -Prosíme všimněte si, že šipkové funkce jsou zvláštní: nemají `this`. Když uvnitř šipkové funkce přistoupíme k `this`, převezme se zvnějšku. +Please note that arrow functions are special: they have no `this`. When `this` is accessed inside an arrow function, it is taken from outside.