|
1 | 1 |
|
2 | | -# Reference Type |
| 2 | +# Referenční typ |
3 | 3 |
|
4 | | -```warn header="In-depth language feature" |
5 | | -This article covers an advanced topic, to understand certain edge-cases better. |
| 4 | +```warn header="Hlubší vlastnost jazyka" |
| 5 | +Tento článek se zabývá pokročilým tématem, abychom lépe porozuměli určitým okrajovým případům. |
6 | 6 |
|
7 | | -It's not important. Many experienced developers live fine without knowing it. Read on if you want to know how things work under the hood. |
| 7 | +Toto téma není důležité. Mnoho zkušených vývojářů žije šťastně i bez jeho znalosti. Článek si přečtěte, pokud chcete vědět, jak fungují věci „pod kapotou“. |
8 | 8 | ``` |
9 | 9 |
|
10 | | -A dynamically evaluated method call can lose `this`. |
| 10 | +Dynamicky vyhodnocované volání metody může ztratit `this`. |
11 | 11 |
|
12 | | -For instance: |
| 12 | +Například: |
13 | 13 |
|
14 | 14 | ```js run |
15 | | -let user = { |
16 | | - name: "John", |
17 | | - hi() { alert(this.name); }, |
18 | | - bye() { alert("Bye"); } |
| 15 | +let uživatel = { |
| 16 | + jméno: "Jan", |
| 17 | + ahoj() { alert(this.jméno); }, |
| 18 | + nashle() { alert("Nashle"); } |
19 | 19 | }; |
20 | 20 |
|
21 | | -user.hi(); // works |
| 21 | +uživatel.ahoj(); // funguje |
22 | 22 |
|
23 | | -// now let's call user.hi or user.bye depending on the name |
| 23 | +// nyní podle jména zavolejme uživatel.ahoj nebo uživatel.nashle |
24 | 24 | *!* |
25 | | -(user.name == "John" ? user.hi : user.bye)(); // Error! |
| 25 | +(uživatel.jméno == "Jan" ? uživatel.ahoj : uživatel.nashle)(); // Chyba! |
26 | 26 | */!* |
27 | 27 | ``` |
28 | 28 |
|
29 | | -On the last line there is a conditional operator that chooses either `user.hi` or `user.bye`. In this case the result is `user.hi`. |
| 29 | +Na posledním řádku je podmíněný operátor, který vybere buď `uživatel.ahoj`, nebo `uživatel.nashle`. V tomto případě je výsledek `uživatel.ahoj`. |
30 | 30 |
|
31 | | -Then the method is immediately called with parentheses `()`. But it doesn't work correctly! |
| 31 | +Pak je tato metoda okamžitě volána pomocí závorek `()`. Ale nefunguje to správně! |
32 | 32 |
|
33 | | -As you can see, the call results in an error, because the value of `"this"` inside the call becomes `undefined`. |
| 33 | +Jak vidíte, výsledkem volání je chyba, protože hodnota `"this"` uvnitř volání se stala `undefined`. |
34 | 34 |
|
35 | | -This works (object dot method): |
| 35 | +Tohle funguje (objekt tečka metoda): |
36 | 36 | ```js |
37 | | -user.hi(); |
| 37 | +uživatel.ahoj(); |
38 | 38 | ``` |
39 | 39 |
|
40 | | -This doesn't (evaluated method): |
| 40 | +Tohle ne (vyhodnocená metoda): |
41 | 41 | ```js |
42 | | -(user.name == "John" ? user.hi : user.bye)(); // Error! |
| 42 | +(uživatel.jméno == "Jan" ? uživatel.ahoj : uživatel.nashle)(); // Chyba! |
43 | 43 | ``` |
44 | 44 |
|
45 | | -Why? If we want to understand why it happens, let's get under the hood of how `obj.method()` call works. |
| 45 | +Proč? Chceme-li porozumět, proč se to děje, podívejme se na zoubek tomu, jak funguje volání `obj.metoda()`. |
46 | 46 |
|
47 | | -## Reference type explained |
| 47 | +## Vysvětlení referenčního typu |
48 | 48 |
|
49 | | -Looking closely, we may notice two operations in `obj.method()` statement: |
| 49 | +Když se podíváme pozorněji, můžeme si v příkazu `obj.metoda()` všimnout dvou operací: |
50 | 50 |
|
51 | | -1. First, the dot `'.'` retrieves the property `obj.method`. |
52 | | -2. Then parentheses `()` execute it. |
| 51 | +1. Nejprve tečka `'.'` získá vlastnost `obj.metoda`. |
| 52 | +2. Pak ji závorky `()` spustí. |
53 | 53 |
|
54 | | -So, how does the information about `this` get passed from the first part to the second one? |
| 54 | +Jak se tedy informace o `this` předá z první části do druhé? |
55 | 55 |
|
56 | | -If we put these operations on separate lines, then `this` will be lost for sure: |
| 56 | +Umístíme-li tyto operace na samostatné řádky, pak bude `this` zcela jistě ztraceno: |
57 | 57 |
|
58 | 58 | ```js run |
59 | | -let user = { |
60 | | - name: "John", |
61 | | - hi() { alert(this.name); } |
62 | | -}; |
| 59 | +let uživatel = { |
| 60 | + jméno: "Jan", |
| 61 | + ahoj() { alert(this.jméno); } |
| 62 | +} |
63 | 63 |
|
64 | 64 | *!* |
65 | | -// split getting and calling the method in two lines |
66 | | -let hi = user.hi; |
67 | | -hi(); // Error, because this is undefined |
| 65 | +// rozdělíme získání a volání metody na dva řádky |
| 66 | +let ahoj = uživatel.ahoj; |
| 67 | +ahoj(); // Chyba, protože this je undefined |
68 | 68 | */!* |
69 | 69 | ``` |
70 | 70 |
|
71 | | -Here `hi = user.hi` puts the function into the variable, and then on the last line it is completely standalone, and so there's no `this`. |
| 71 | +Zde `ahoj = uživatel.ahoj` vloží funkci do proměnné a ta je pak na posledním řádku zcela samostatná, takže tam není žádné `this`. |
72 | 72 |
|
73 | | -**To make `user.hi()` calls work, JavaScript uses a trick -- the dot `'.'` returns not a function, but a value of the special [Reference Type](https://tc39.github.io/ecma262/#sec-reference-specification-type).** |
| 73 | +**Aby volání `uživatel.ahoj()` fungovalo, JavaScript používá trik -- tečka `'.'` nevrací funkci, ale hodnotu speciálního [referenčního typu](https://tc39.github.io/ecma262/#sec-reference-specification-type).** |
74 | 74 |
|
75 | | -The Reference Type is a "specification type". We can't explicitly use it, but it is used internally by the language. |
| 75 | +Referenční typ je „specifikační typ“. Nemůžeme jej explicitně používat, ale je používán vnitřně jazykem. |
76 | 76 |
|
77 | | -The value of Reference Type is a three-value combination `(base, name, strict)`, where: |
| 77 | +Hodnotou referenčního typu je tříhodnotová kombinace `(base, name, strict)`, kde: |
78 | 78 |
|
79 | | -- `base` is the object. |
80 | | -- `name` is the property name. |
81 | | -- `strict` is true if `use strict` is in effect. |
| 79 | +- `base` (základ) je objekt. |
| 80 | +- `name` (název) je název vlastnosti. |
| 81 | +- `strict` (striktní) je true, pokud je použito `use strict`. |
82 | 82 |
|
83 | | -The result of a property access `user.hi` is not a function, but a value of Reference Type. For `user.hi` in strict mode it is: |
| 83 | +Výsledkem přístupu k vlastnosti `uživatel.ahoj` není funkce, ale hodnota referenčního typu. Pro `uživatel.ahoj` ve striktním režimu to je: |
84 | 84 |
|
85 | 85 | ```js |
86 | | -// Reference Type value |
87 | | -(user, "hi", true) |
| 86 | +// hodnota referenčního typu |
| 87 | +(uživatel, "ahoj", true) |
88 | 88 | ``` |
89 | 89 |
|
90 | | -When parentheses `()` are called on the Reference Type, they receive the full information about the object and its method, and can set the right `this` (`user` in this case). |
| 90 | +Když se na referenčním typu zavolají závorky `()`, obdrží úplnou informaci o objektu a jeho metodě a mohou tedy nastavit správné `this` (v tomto případě `uživatel`). |
91 | 91 |
|
92 | | -Reference type is a special "intermediary" internal type, with the purpose to pass information from dot `.` to calling parentheses `()`. |
| 92 | +Referenční typ je speciální „zprostředkovatelský“ interní typ, jehož účelem je předat informaci z tečky `.` volajícím závorkám `()`. |
93 | 93 |
|
94 | | -Any other operation like assignment `hi = user.hi` discards the reference type as a whole, takes the value of `user.hi` (a function) and passes it on. So any further operation "loses" `this`. |
| 94 | +Jakákoli jiná operace, např. přiřazení `ahoj = uživatel.ahoj`, celý referenční typ zahodí, vezme hodnotu `uživatel.ahoj` (funkci) a předá ji dál. Jakákoli další operace tedy „ztratí“ `this`. |
95 | 95 |
|
96 | | -So, as the result, the value of `this` is only passed the right way if the function is called directly using a dot `obj.method()` or square brackets `obj['method']()` syntax (they do the same here). There are various ways to solve this problem such as [func.bind()](/bind#solution-2-bind). |
| 96 | +Výsledkem tedy je, že hodnota `this` se předá správně jen tehdy, je-li funkce volána přímo pomocí syntaxe tečky `obj.metoda()` nebo hranatých závorek `obj['metoda']()` (obojí zde provádí totéž). Existují různé způsoby, jak tento problém vyřešit, např. [funkce.bind()](/bind#solution-2-bind). |
97 | 97 |
|
98 | | -## Summary |
| 98 | +## Shrnutí |
99 | 99 |
|
100 | | -Reference Type is an internal type of the language. |
| 100 | +Referenční typ je interní jazykový typ. |
101 | 101 |
|
102 | | -Reading a property, such as with dot `.` in `obj.method()` returns not exactly the property value, but a special "reference type" value that stores both the property value and the object it was taken from. |
| 102 | +Načtení vlastnosti, např. pomocí tečky `.` v `obj.metoda()`, nevrací přesně hodnotu vlastnosti, ale speciální hodnotu „referenčního typu“, v níž je uložena jak hodnota vlastnosti, tak objekt, z něhož byla převzata. |
103 | 103 |
|
104 | | -That's for the subsequent method call `()` to get the object and set `this` to it. |
| 104 | +To je proto, aby následné volání metody `()` mohlo získat objekt a nastavit jej jako `this`. |
105 | 105 |
|
106 | | -For all other operations, the reference type automatically becomes the property value (a function in our case). |
| 106 | +Při všech ostatních operacích se z referenčního typu automaticky stává hodnota vlastnosti (v našem případě funkce). |
107 | 107 |
|
108 | | -The whole mechanics is hidden from our eyes. It only matters in subtle cases, such as when a method is obtained dynamically from the object, using an expression. |
| 108 | +Celá tato mechanika je před našima očima ukryta. Záleží na ní jen v krajních případech, například když je metoda získána z objektu dynamicky použitím výrazu. |
0 commit comments