Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork3
The "new Function" syntax#169
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
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
106 changes: 53 additions & 53 deletions1-js/06-advanced-functions/07-new-function/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,123 +1,123 @@ | ||
#Syntaxe „new Function“ | ||
Existuje ještě jeden způsob, jak vytvořit funkci. Používá se jen zřídka, ale někdy nemáme jinou možnost. | ||
##Syntaxe | ||
Syntaxe vytvoření funkce: | ||
```js | ||
letfunkce = new Function ([arg1, arg2, ...argN],těloFunkce); | ||
``` | ||
Funkce je vytvořena s argumenty`arg1...argN`a zadaným tělem `těloFunkce`. | ||
Je snadnější tomu porozumět, když se podíváme na příklad. Toto je funkce se dvěma argumenty: | ||
```js run | ||
letsečti = new Function('a', 'b', 'return a + b'); | ||
alert(sečti(1, 2) ); // 3 | ||
``` | ||
A zde je funkce bez argumentů, jenom s tělem: | ||
```js run | ||
letřekniAhoj = new Function('alert("Ahoj")'); | ||
řekniAhoj(); //Ahoj | ||
``` | ||
Hlavní rozdíl oproti ostatním způsobům, jaké jsme viděli, je, že funkce je vytvořena doslovně z řetězce, který je předán za běhu skriptu. | ||
Všechny předchozí deklarace po nás programátorech požadovaly, abychom zapsali kód funkce do skriptu. | ||
Avšak `new Function`umožňuje převést libovolný řetězec na funkci. Například můžeme získat novou funkci ze serveru a pak ji spustit: | ||
```js | ||
letřetězec = ...dynamické získání kódu ze serveru ... | ||
letfunkce = new Function(řetězec); | ||
funkce(); | ||
``` | ||
Používá se jen ve velmi specifických případech, například když získáme kód ze serveru, nebo když chceme dynamicky kompilovat funkci ze šablony ve složitých webových aplikacích. | ||
##Uzávěr | ||
Funkce si zpravidla pamatuje, kde se zrodila, ve speciální vlastnosti`[[Environment]]`.Ta se odkazuje na lexikální prostředí, z něhož byla funkce vytvořena (probrali jsme to v kapitole <info:closure>). | ||
Když je však funkce vytvořena pomocí`new Function`,její vlastnost`[[Environment]]`se nenastaví na odkaz na aktuální lexikální prostředí, ale na globální. | ||
Taková funkce tedy nemá přístup k vnějším proměnným, jedině ke globálním. | ||
```js run | ||
functionvraťFunkci() { | ||
lethodnota = "test"; | ||
*!* | ||
letfunkce = new Function('alert(hodnota)'); | ||
*/!* | ||
returnfunkce; | ||
} | ||
vraťFunkci()(); //chyba: hodnota není definována | ||
``` | ||
Porovnejte si to s běžným chováním: | ||
```js run | ||
functionvraťFunkci() { | ||
lethodnota = "test"; | ||
*!* | ||
letfunkce = function() { alert(hodnota); }; | ||
*/!* | ||
returnfunkce; | ||
} | ||
vraťFunkci()(); // *!*"test"*/!*,z lexikálního prostředí funkce vraťFunkci | ||
``` | ||
Tato speciální vlastnost`new Function`vypadá zvláštně, ale v praxi se ukazuje být velmi užitečná. | ||
Představme si, že musíme vytvořit funkci z řetězce. Kód této funkce není znám v době psaní skriptu (to je důvod, proč nepoužijeme obvyklou funkci),ale bude znám při jeho běhu. Můžeme jej získat ze serveru nebo z jiného zdroje. | ||
Naše nová funkce musí interagovat s hlavním skriptem. | ||
Co kdyby mohla přistupovat k vnějším proměnným? | ||
Problém je v tom, že předtím, než je JavaScriptový skript zveřejněn k používání, je zkomprimován *minifikátorem* --speciálním programem, který zkrátí kód tím, že odstraní komentáře, přebytečné mezery a--co je důležité, přejmenuje názvy lokálních proměnných na kratší. | ||
Například jestliže funkce obsahuje`letuživatelskéJméno`,minifikátor je nahradí za `let a` (nebo jiné písmeno, které ještě není použito) a učiní tak všude. To je obvykle bezpečné, jelikož proměnná je lokální a nic mimo funkci k ní nemůže přistupovat. A uvnitř funkce minifikátor nahradí tuto proměnnou všude, kde je uvedena. Minifikátory jsou chytré, analyzují strukturu kódu, takže nic nerozbíjejí. Není to jen tupé najdi anahraď. | ||
Kdyby tedy `new Function`měla přístup k vnějším proměnným, nedokázala by najít přejmenované `uživatelskéJméno`. | ||
**Kdyby `new Function`měla přístup k vnějším proměnným, měla by problémy s minifikátory.** | ||
Navíc by takový kód byl architektonicky špatný a náchylný k chybám. | ||
K tomu, abychom něco předali funkci vytvořené pomocí `new Function`,bychom měli používat její argumenty. | ||
##Shrnutí | ||
Syntaxe: | ||
```js | ||
letfunkce = new Function ([arg1, arg2, ...argN],těloFunkce); | ||
``` | ||
Z historických důvodů můžeme argumenty uvést i jako seznam oddělený čárkou. | ||
Tyto tři deklarace znamenají totéž: | ||
```js | ||
new Function('a', 'b', 'return a + b'); //základní syntaxe | ||
new Function('a,b', 'return a + b'); //oddělené čárkou | ||
new Function('a , b', 'return a + b'); //oddělené čárkou s mezerami | ||
``` | ||
Vlastnost `[[Environment]]` funkcí vytvořených pomocí`new Function` se odkazuje na globální lexikální prostředí, ne na vnější. Proto tyto funkce nemohou používat vnější proměnné. To je však ve skutečnosti dobře, protože nás to ochraňuje před chybami. Výslovné předávání parametrů je architektonicky mnohem lepší způsob a nezpůsobuje problémy s minifikátory. |
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.