¿Por qué existe eval ()?


Muchos programadores dicen que es una práctica mala usar la función eval():

¿Cuándo eval() de JavaScript no es malo?

Me gustaría tomar un momento para abordar la premisa de tu pregunta - que eval() es "malvado"...

¿Es esto eval () peligroso?

El código con errores evaled puede violar las propiedades de seguridad tan fácilmente como el código fuente con errores...

¿Por qué no eval () JSON?

Allí son varias las formas en que su seguridad puede verse comprometida...

¿Hay alguna vez una buena razón para usar eval ()?

Sí - cuando no hay otra manera de cumplir la tarea dada con un nivel razonable de claridad... Esto elimina el 99% de los casos en los que se utiliza eval...

¿Por qué eval es inseguro en javascript?

El peligro de eval solo levanta su fea cabeza cuando estás sirviendo un guion escrito por alice al usuario bob para que el navegador de Bob evalúe...


Entonces, ¿por qué existe en primer lugar?

Author: Community, 2012-02-01

6 answers

Porque a veces hay una necesidad. Todas las mismas razones para/en contra de usar eval en JavaScript pueden ser compartidas con el uso de reflexión en Java, por ejemplo.

Sin embargo, estoy de acuerdo con todo lo que ha citado en su pregunta. Muchas razones para usarlo son desaconsejadas, y es mejor hacerlo de manera diferente, pero a veces, todavía hay una necesidad, o simplemente es la "mejor opción" sobre otras alternativas disponibles. (Me centraría en las respuestas a ¿Hay alguna vez una buena razón para usar eval ()? por razones adicionales.)

+ 1 a su pregunta para una buena investigación.

 8
Author: ziesemer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:48:25

eval() existe porque a veces quiere dar un control programático completo de su aplicación al código pasado en tiempo de ejecución.

Los lenguajes sin una característica eval() definitivamente pueden proporcionar (¿un subconjunto? todos?) de esta funcionalidad pidiendo a cada programador que esencialmente escriba su propio eval() -- lex la entrada, analizar la entrada, crear nuevos objetos según sea necesario, ejecutar métodos o funciones en ellos a través de comparaciones de cadenas simples o similares. En esencia, duplicar la intérprete completo que ya existe y es depurado y rápido.

 8
Author: sarnold,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-01 01:35:02

Eval es en realidad una característica poderosa y hay algunas cosas que son imposibles de hacer sin ella. Por ejemplo:

  1. Evalúe el código recibido de un servidor remoto. (Supongamos que desea crear un sitio que pueda controlarse de forma remota mediante el envío de código JavaScript a él?)
  2. Evalúe el código escrito por el usuario. Sin eval, no se puede programar, por ejemplo, un editor en línea / REPL.
  3. Creando funciones de longitud arbitraria dinámicamente (function.longitud es readonly, por lo que el único manera está utilizando eval).
  4. Cargando un script y devolviendo su valor. Si su script es, por ejemplo, una función auto-llamada, y desea evaluarla y obtener su resultado (por ejemplo: my_result = get_script_result("foo.js")), la única forma de programar la función get_script_result es usando eval dentro de ella.
  5. Volver a crear una función en un cierre diferente.

Y cualquier otra cosa que quieras hacer implica crear código sobre la marcha.

La razón por la que se considera "malo" es porque es usado clásicamente por principiantes para hacer cosas que el lenguaje puede manejar de forma nativa. Por ejemplo, el siguiente código:

age_of_erick = 34;
age_of_john = 21;
person = "erick";
eval("console.log('age_of_"+person+"')");

Y el siguiente código:

age = {erick:34, john:21};
person = "erick";
console.log(age["erick"]);

Ambos hacen lo mismo, excepto que uno analiza una cadena, genera código a partir de ella, compila en código máquina y luego ejecuta, mientras que el otro lee un valor de un hash, que es mucho más rápido.

 6
Author: MaiaVictor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-13 18:08:28

Hay una publicación de investigación exacta sobre este tema:

El Eval Que Hacen los Hombres -- Un Estudio a Gran escala del Uso de Eval en Aplicaciones JavaScript
Espejo en Wayback Machine

Es para mí la respuesta más completa a esta pregunta hasta la fecha.

Cita del resumen:

Hemos registrado el comportamiento de 337 MB de cadenas dadas como argumentos a 550.358 llamadas a la función eval ejercitada en más de 10,000 web sites.

Entre otras, identificaron 9 categorías de recurrentes eval:

  1. JSON - Una cadena o variante JSON.
  2. JSONP - Una cadena JSON acolchada.
  3. Biblioteca-Una o más definiciones de funciones.
  4. Read - Acceso de lectura a una propiedad del objeto.
  5. Assign-Asignación a una variable local o propiedad del objeto.
  6. Typeof - Expresión de prueba de tipo.
  7. Try-Trivial bloque try / catch.
  8. Llamada-Simple llamada a función / método.
  9. Vacío - Cadena vacía o en blanco.

Un fragmento de la conclusión (que es demasiado largo para ser citado por completo):

[...] Mientras que muchos usos eval eran legítimos, muchos eran innecesarios y podría sustituirse por un código equivalente y más seguro. Empezamos este trabajo con la esperanza de que demostraría que eval puede ser reemplazado por otros función. Lamentablemente, nuestros datos no apoyan esta conclusión.[...]

Un pozo de papel vale la pena leerlo.

 6
Author: ewernli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-11 17:35:00

La función eval() es como tijeras. Eres un adulto, es tu responsabilidad no correr con ellos.

He visto la filosofía de diseño de los lenguajes dinámicos (como JavaScript) resumida como preferir permitir que las personas inteligentes hagan cosas inteligentes por encima de tratar de evitar que las personas estúpidas hagan cosas tontas. (Desafortunadamente no puedo recordar la fuente original o el fraseo.)

Si te preocupa introducir errores con eval, puedes usar modo estricto. Parece que evite algunos de los problemas con el diseño de la función. (Es decir, como una función "mágica" permite clobber su espacio de nombres.)

 2
Author: millimoose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-01 01:40:41

Eval existe para simplificar tareas en JavaScript. Puede usarlo para evaluar varias sentencias. En lugar de tener que encontrar otra manera, puedes usar eval para hacer tales cosas. A pesar de que se desaconseja, tiene un poder y un uso considerables.

 0
Author: genius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-11 17:30:05