2012-02-01 16 views
27

Muchos programadores dicen que es una mala prácticautilizar la función eval():¿Por qué eval() existe?

When is JavaScript's eval() not evil?

me gustaría tomar un momento para hacer frente a la premisa de su pregunta - que eval() es "mal" ...

Is this eval() dangerous?

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

Why not eval() JSON?

Hay un número de maneras en que su seguridad puede verse comprometida ...

Is there ever a good reason to use eval()?

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

Why is eval unsafe in javascript?

El peligro de eval sólo se asoma su fea cabeza cuando se está sirviendo un guión escrito por Alice a Bob de usuario para el navegador de bob a eval ...


Entonces, ¿por qué existe en primer lugar?

+3

¿Por qué los hombres escalan montañas? –

+2

@JoelCoehoorn, para llegar al otro lado? –

Respuesta

7

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

Sin embargo, estoy de acuerdo con todo lo que citó en su pregunta. Muchas razones para usarlo son desacertadas, y lo mejor es 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 Is there ever a good reason to use eval()? por razones adicionales.)

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

+2

Felizmente agregando otro +1 para la buena investigación. El 99% de los casos evitables es cierto. El 1% - cosas como http://dean.edwards.name/packer/ - habría sido una locura escribir sin él;) –

+0

@Chris Great of a valid use case. Estaba tratando de averiguar si [Firebug Lite] (http://getfirebug.com/firebuglite) utiliza 'eval' para su control JS, pero se perdió en su código. – millimoose

+0

Hay una publicación de investigación reciente sobre el tema que podría interesarle. Su conclusión coincide con su intuición/experiencia. Ver mi respuesta – ewernli

2

La función eval() es como una tijera. 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) que se resumen porque prefieren permitir que las personas inteligentes hagan cosas inteligentes antes que tratar de evitar que las personas estúpidas hagan cosas tontas. (Desafortunadamente no puedo recordar la fuente original o el fraseo.)

Si le preocupa la introducción de errores con eval, puede usar strict mode.Parece prevenir algunos de los problemas con el diseño de la función. (Es decir, como una función de "mágica" permitió a darle una paliza a su espacio de nombres.)

8

eval() existe porque a veces se desea para dar control de programación completa de su aplicación para codificar aprobada en en tiempo de ejecución.

idiomas sin duda una característica eval() puede proporcionar (?? Un subconjunto todos) de esta funcionalidad pidiendo a cada programador escribir esencialmente su propia eval() - Lex la entrada, se analiza la entrada, crear nuevos objetos como sea necesario, ejecutar métodos o funciones en ellos a través de comparaciones de cadenas simples o similares. Básicamente, duplique todo el intérprete que ya existe y que esté depurado y rápido.

6

Hay una investigación exacty publicación sobre este tema:

The Eval That Men Do -- A Large-scale Study of the Use of Eval in JavaScript Applications
Mirror on Wayback Machine

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

Cita de lo abstracto:

Hemos registrado el comportamiento de 337 MB de cadenas dados como argumentos a 550,358 llamadas a la función eval ejercidas en más de 10.000 sitios web .

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

  1. JSON - Una cadena JSON o variante.
  2. JSONP - Una cadena JSON acolchada.
  3. Biblioteca: una o más de fi niciones de funciones.
  4. Acceso de lectura a lectura a la propiedad de un objeto .
  5. Asignar - Asignación a una variable local o propiedad de objeto .
  6. Typeof - Type test expression.
  7. Try - Trivial try/catch block.
  8. Llamada - Función simple/llamada de método.
  9. Vacío - Cadena vacía o en blanco.

Un fragmento de la conclusión (que es demasiado larga para ser reproducida entierly):

[...] Si bien muchos usos eval eran legítimos, muchos eran innecesarios y podría sustituirse con un equivalente y un código más seguro. Comenzamos este trabajo con la esperanza de que demuestre que eval se puede reemplazar por otras características de . Lamentablemente, nuestros datos no respaldan esta conclusión. [...]

Un papel que vale la pena leer.

6

Eval es en realidad una característica poderosa y hay algunas cosas que son imposible para prescindir de ella. Por ejemplo:

  1. Evalúa 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)
  2. Evalúe el código escrito por el usuario. Sin eval, no puede programar, por ejemplo, un editor en línea/REPL.
  3. Creación de funciones de longitud arbitraria de forma dinámica (function.length es de solo lectura, por lo que la única forma es usar eval).
  4. Cargando una secuencia de comandos y devolviendo su valor. Si su script es, por ejemplo, una función de autoexploración, y desea evaluarlo y obtener su resultado (p. Ej .: my_result = get_script_result("foo.js")), la única forma de programar la función get_script_result es mediante el uso de eval dentro de ella.
  5. Volver a crear una función en un cierre diferente.

Y cualquier cosa que desee hacer que implica la creación de código sobre la marcha.

La razón por la que se considera "malo" se debe a que los novatos lo usan de forma clásica para hacer cosas que el idioma puede manejar de forma nativa. Por ejemplo, el código de abajo:

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

Y el código de abajo:

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

Ambos hacen lo mismo, excepto una analiza una cadena, genera código de él, 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.

0

Eval existe para simplificar tareas en JavaScript. Puedes usarlo para evaluar múltiples declaraciones. En lugar de tener que encontrar otra forma, puede usar eval para hacer tales cosas. A pesar de que se desaconseja, tiene una potencia y un uso considerables.