- Notifications
You must be signed in to change notification settings - Fork230
The "new Function" syntax#120
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
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
864c942ad451086aeaa82ae90bc2dd2618c1c95fe23f738d9431bb77244f96685c2e8062972aa1eeddda0859772File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,123 +1,125 @@ | ||||||||||
| # La sintaxis "new Function" | ||||||||||
| Hay una forma más de crear una función. Raramente se usa, pero a veces no hay alternativa. | ||||||||||
| ## Sintaxis | ||||||||||
| La sintaxis para crear una función: | ||||||||||
| ```js | ||||||||||
| let func = new Function ([arg1, arg2, ...argN], functionBody); | ||||||||||
| ``` | ||||||||||
| La función se crea con los argumentos `arg1...argN`y el`functionBody` dado. | ||||||||||
| Es más fácil entender viendo un ejemplo: Aquí tenemos una función con dos argumentos: | ||||||||||
| ```js run | ||||||||||
| let sumar = new Function('a', 'b', 'return a + b'); | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| alert(sumar(1, 2)); // 3 | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| ``` | ||||||||||
| Si no hay argumentos, entonces hay sólo un único argumento, el cuerpo de la función sería: | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| ```js run | ||||||||||
| letdiHola = new Function('alert("Hola")'); | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| diHola(); //Hola | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| ``` | ||||||||||
| La mayor diferencia sobre las otras maneras de crear funciones que hemos visto, es que la función se crea literalmente con un string y es pasada en tiempo de ejecución. | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
no se crea "con un string" sino "a partir de una cadena" | ||||||||||
| Las declaraciones anteriores nos obliga a nosotros, los programadores, a escribir el código de la función en el script. | ||||||||||
EzequielCaste marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||||||||||
| Pero `new Function` nos permite convertir cualquier string en una función. Por ejemplo, podemos recibir una nueva función desde el servidor y ejecutarlo. | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| ```js | ||||||||||
| let str = ...recibir el código de un servidor dinámicamente ... | ||||||||||
EzequielCaste marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| let func = new Function(str); | ||||||||||
| func(); | ||||||||||
| ``` | ||||||||||
| Se utilizan en casos muy específicos, como cuando recibimos código de un servidor, o compilar dinámicamente una función a partir de una plantilla. La necesidad surge en etapas avanzadas de desarrollo. | ||||||||||
EzequielCaste marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| ## Closure | ||||||||||
| Normalmente, una función recuerda dónde nació en una propiedad especial llamada`[[Environment]]`.Hace referencia al entorno léxico desde dónde se creó. | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| Pero cuando una función es creada usando `new Function`,su `[[Environment]]`no hace referencia al entorno léxico actual, sino al global. | ||||||||||
| So, such function doesn't have access to outer variables, only to the global ones. | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| ```js run | ||||||||||
| function getFunc() { | ||||||||||
| letvalor = "test"; | ||||||||||
| *!* | ||||||||||
| let func = new Function('alert(valor)'); | ||||||||||
| */!* | ||||||||||
| return func; | ||||||||||
| } | ||||||||||
| getFunc()(); // error:valor is not defined | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| ``` | ||||||||||
| Compáralo con el comportamiento normal: | ||||||||||
| ```js run | ||||||||||
| function getFunc() { | ||||||||||
| letvalor = "test"; | ||||||||||
| *!* | ||||||||||
| let func = function() { alert(valor); }; | ||||||||||
| */!* | ||||||||||
| return func; | ||||||||||
| } | ||||||||||
| getFunc()(); // *!*"test"*/!*,obtenido del entorno léxico de getFunc | ||||||||||
| ``` | ||||||||||
| Esta característica especial de `new Function`parece estraño, pero parece muy útil en la práctica. | ||||||||||
EzequielCaste marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| Imagina que debemos crear una funcion apartir de una string.El código de dicha función no se conoce al momento de escribir elscript (es por eso que no usamos funciones regulares),pero se conocerá en el proceso de ejecución. Podemos recibirlo del servidor o de otra fuente. | ||||||||||
| ¿Quizás queremos que pueda acceder a las variables locales externas? | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| El problema es que antes de publicar el JavaScript a producción, este es comprimido usando un _minifier_ -- un programa especial que comprime código elimiando los comentarios extras, espacios -- y lo que es más importante, renombra lasvariables locales a otras más cortas. | ||||||||||
EzequielCaste marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| Por ejemplo, si una función tiene `let userName`, el _minifier_ lo reemplaza a `let a` (o otra letra si esta está siendo utilizada), y lo hace en todas partes. Esto es normalmente una práctica segura, al ser una variable local, nada de fuera de la función puede acceder a ella. Y dentro de una función, el _minifier_ reemplaza todo lo que le menciona. Los Minificadores son inteligiente, ellos analizan la estructura del código, por lo tanto, no rompen nada. No realizan un simple buscar y reemplazar. | ||||||||||
EzequielCaste marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| Pero, si `new Function` puede acceder a las variables externas, entonces no podría encontrar `userName`, ya que esto es pasada como un string _después_ de que el código haya sido minificado. | ||||||||||
EzequielCaste marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| **Incluso si podemos acceder al entorno léxico con `new Function`, tendríamos problemas con los minificadores** | ||||||||||
EzequielCaste marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| La "característica especial" de`new Function`nos salva de errores. | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| Y obliga a un mejor código. Si necesitamos pasarle algo a la función creada con `new Function`, debemos pasarle explícitamente como argumento. | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change | ||||||||||
| Nuestra función "suma" lo hace bien: | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change | ||||||||||
| ```js run | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| *!* | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| let suma = new Function('a', 'b', 'return a + b'); | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| */!* | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change | ||||||||||
| let a = 1, b = 2; | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| *!* | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| // outer values are passed as arguments | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| alert( sum(a, b) ); // 3 | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| */!* | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| ``` | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| ## Resumen | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| La sintáxis: | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| ```js | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| let func = new Function ([arg1, arg2, ...argN], functionBody); | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| ``` | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| Por razones históricas, los argumentos también pueden ser pasados como una lista separada por comas. | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| Estos tres significan lo mismo: | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
| ```js | ||||||||||
| new Function('a', 'b', 'return a + b'); // sintáxis básica | ||||||||||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||