Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork3
Reference Type#212
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Merged
Uh oh!
There was an error while loading.Please reload this page.
Merged
Reference Type#212
Changes fromall commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
34 changes: 17 additions & 17 deletions1-js/99-js-misc/04-reference-type/2-check-syntax/solution.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,37 @@ | ||
**Chyba!** | ||
Zkuste si to: | ||
```js run | ||
letuživatel = { | ||
jméno: "Jan", | ||
jdi: function() { alert(this.jméno) } | ||
} | ||
(uživatel.jdi)() //chyba! | ||
``` | ||
Ve většině prohlížečů nám chybová zpráva nedává mnoho informací o tom, co bylo špatně. | ||
**Chyba se objevila proto, že za `uživatel = {...}` chybí středník.** | ||
JavaScriptautomaticky nevloží středník před závorku `(uživatel.jdi)()`,takže přečte kód jako: | ||
```js no-beautify | ||
letuživatel = {jdi:... }(uživatel.jdi)() | ||
``` | ||
Pak také vidíme, že takový spojený výraz je syntakticky voláním objektu`{jdi: ... }`jako funkce s argumentem `(uživatel.jdi)`.A to se také odehrává na stejném řádku jako `letuživatel`,takže objekt `uživatel` ještě ani nebyl definován, proto nastane chyba. | ||
Jestliže vložíme středník, bude vše v pořádku: | ||
```js run | ||
letuživatel = { | ||
jméno: "Jan", | ||
jdi: function() { alert(this.jméno) } | ||
}*!*;*/!* | ||
(uživatel.jdi)() //Jan | ||
``` | ||
Prosíme všimněte si, že závorky okolo `(uživatel.jdi)`tady nic nedělají. Obvykle nastavují pořadí operací, ale tady jako první zafunguje tečka`.`tak jako tak, takže závorky nemají žádný efekt. Vadí jenom chybějící středník. |
14 changes: 7 additions & 7 deletions1-js/99-js-misc/04-reference-type/2-check-syntax/task.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
20 changes: 10 additions & 10 deletions1-js/99-js-misc/04-reference-type/3-why-this/solution.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,22 @@ | ||
Zde je vysvětlení. | ||
1.Toto je běžné volání metody objektu. | ||
2.Totéž, závorky tady nezmění pořadí operací, tečka je i tak první. | ||
3.Zde máme složitější volání `(výraz)()`.Toto volání funguje tak, jako by bylo rozděleno na dva řádky: | ||
```js no-beautify | ||
f = obj.jdi; //vypočítáme výraz | ||
f();//zavoláme to, co máme | ||
``` | ||
Zde se`f()`spustí jako funkce bez `this`. | ||
4.Podobně jako`(3)`,nalevo od závorek`()`máme výraz. | ||
Abychom vysvětlili chování`(3)`a `(4)`, musíme si vzpomenout, že operátory přístupu k vlastnostem (tečka nebo hranaté závorky) vracejí hodnotu referenčního typu. | ||
Jakákoli operace na ní kromě volání metody (např. přiřazení `=`, nebo `||`)ji změní na obyčejnou hodnotu, která neobsahuje informaci umožňující nastavit `this`. | ||
18 changes: 9 additions & 9 deletions1-js/99-js-misc/04-reference-type/3-why-this/task.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
108 changes: 54 additions & 54 deletions1-js/99-js-misc/04-reference-type/article.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,108 +1,108 @@ | ||
#Referenční typ | ||
```warn header="Hlubší vlastnost jazyka" | ||
Tento článek se zabývá pokročilým tématem, abychom lépe porozuměli určitým okrajovým případům. | ||
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“. | ||
``` | ||
Dynamicky vyhodnocované volání metody může ztratit `this`. | ||
Například: | ||
```js run | ||
letuživatel = { | ||
jméno: "Jan", | ||
ahoj() { alert(this.jméno); }, | ||
nashle() { alert("Nashle"); } | ||
}; | ||
uživatel.ahoj(); //funguje | ||
//nyní podle jména zavolejme uživatel.ahoj nebo uživatel.nashle | ||
*!* | ||
(uživatel.jméno == "Jan" ?uživatel.ahoj :uživatel.nashle)(); //Chyba! | ||
*/!* | ||
``` | ||
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`. | ||
Pak je tato metoda okamžitě volána pomocí závorek `()`.Ale nefunguje to správně! | ||
Jak vidíte, výsledkem volání je chyba, protože hodnota`"this"`uvnitř volání se stala `undefined`. | ||
Tohle funguje (objekt tečka metoda): | ||
```js | ||
uživatel.ahoj(); | ||
``` | ||
Tohle ne (vyhodnocená metoda): | ||
```js | ||
(uživatel.jméno == "Jan" ?uživatel.ahoj :uživatel.nashle)(); //Chyba! | ||
``` | ||
Proč? Chceme-li porozumět, proč setoděje, podívejme se na zoubek tomu, jak funguje volání`obj.metoda()`. | ||
##Vysvětlení referenčního typu | ||
Když se podíváme pozorněji, můžeme si v příkazu `obj.metoda()`všimnout dvou operací: | ||
1.Nejprve tečka`'.'`získá vlastnost`obj.metoda`. | ||
2.Pak ji závorky`()`spustí. | ||
Jak se tedy informace o`this`předá z první části do druhé? | ||
Umístíme-li tyto operace na samostatné řádky, pak bude`this`zcela jistě ztraceno: | ||
```js run | ||
letuživatel = { | ||
jméno: "Jan", | ||
ahoj() { alert(this.jméno); } | ||
} | ||
*!* | ||
//rozdělíme získání a volání metody na dva řádky | ||
letahoj =uživatel.ahoj; | ||
ahoj(); //Chyba, protože thisje undefined | ||
*/!* | ||
``` | ||
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`. | ||
**Aby volání `uživatel.ahoj()`fungovalo, JavaScriptpoužívá trik--tečka`'.'`nevrací funkci, ale hodnotu speciálního [referenčního typu](https://tc39.github.io/ecma262/#sec-reference-specification-type).** | ||
Referenční typ je „specifikační typ“. Nemůžeme jej explicitně používat, ale je používán vnitřně jazykem. | ||
Hodnotou referenčního typu je tříhodnotová kombinace`(base, name, strict)`,kde: | ||
- `base`(základ) je objekt. | ||
- `name`(název) je název vlastnosti. | ||
- `strict`(striktní) jetrue, pokud je použito`use strict`. | ||
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: | ||
```js | ||
//hodnota referenčního typu | ||
(uživatel, "ahoj", true) | ||
``` | ||
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`). | ||
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 `()`. | ||
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`. | ||
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). | ||
##Shrnutí | ||
Referenční typ je interní jazykový typ. | ||
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. | ||
To je proto, aby následné volání metody`()`mohlo získat objekt a nastavit jej jako`this`. | ||
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). | ||
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. |
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.