Cuando estaba implementando el motor JScript, abogaba por que se imprimieran las camisetas EVAL IS EVIL , pero lamentablemente nunca lo hicimos.
Mi mayor problema con eval no es el obvio ataque de inyección de código malicioso, aunque ciertamente es una gran preocupación. Mi mayor problema es que la gente tiende a usarlo como un martillo realmente grande para resolver problemas realmente pequeños. La mayoría de los usos del mundo real que vi de "eval" en la naturaleza cuando estaba en el equipo de JScript podrían haberse resuelto trivialmente usando una tabla de búsqueda; y dado que cada objeto en JScript ya es una tabla de búsqueda, no es como si fuera una carga onerosa. Eval inicia el compilador nuevamente y destruye completamente la capacidad del compilador para optimizar su código .
Para algunas ideas más en este sentido, vea mis artículos de 2003 sobre el tema:
Maldad general:
http://blogs.msdn.com/b/ericlippert/archive/2003/11/01/53329.aspx
Inyección ataque maldad:
http://blogs.msdn.com/b/ericlippert/archive/2003/11/04/53335.aspx
eval
opina sobre la introducción de grandes fragmentos de código de la forma en que les gusta a aplicaciones como JSPacker? JSPacker + gzip generalmente da como resultado tamaños de archivo más pequeños que cualquiera de las soluciones por sí solo, pero como señala correctamente, esencialmente está activando un compilador dos veces en la misma pieza de código, más algo de sobrecarga para hacer reemplazos de cadenas.eval()
es no un riesgo de seguridad en el código de cliente (navegador).La mayoría de los agujeros de seguridad son el mismo tipo de agujeros que con la inyección SQL, es decir, concatenar la entrada del usuario en el código JavaScript. La diferencia es que, si bien hay formas de garantizar que esto no suceda con SQL, no hay mucho que pueda hacer con JavaScript.
Como un ejemplo trivial e inútil, una calculadora JavaScript simplista:
Un ejemplo de uso correcto son algunos de los empaquetadores de JavaScript que comprimen JavaScript al extraer palabras comunes y reemplazarlas con reemplazos cortos de 1-2 caracteres. El empaquetador genera todo esto junto con el código de reemplazo de cadena basado en el diccionario generado y luego evalúa el resultado.
fuente
Hay algunas cosas que son imposibles de hacer en JS sin una función eval-como (
eval
,Function
y tal vez más).Toma
apply
por ejemplo. Es fácil de usar cuando se usa en llamadas a funciones normales:foo.apply(null, [a, b, c])
Pero, ¿cómo haría esto para los objetos que está creando a través de una nueva sintaxis?
new Foo.apply(null, [a, b, c])
no funciona, ni lo hacen formas similares.Pero puede evitar esta limitación a través de
eval
oFunction
(yo usoFunction
en este ejemplo):Ejemplo:
Foo.New.apply(null, [a, b, c])
;Por supuesto, puede construir manualmente las funciones que
Function.prototype.New
usa, pero no solo es detallado y torpe, sino que (por definición) tiene que ser finito.Function
permite que el código funcione para cualquier número de argumentos.fuente
eval()
De qué sirve ? "Una respuesta un tanto directa de mi parte fue desarrollar un área de prueba de API orientada al desarrollador. Le dimos un área de texto en una página y un botón Ejecutar. El punto central de la página era que pudieran probar cosas en Javascript contra nuestra API de comunicación de iframe que no era tan fácil de hacer en un entorno local.
Cualquier cosa maliciosa que podría haberse hecho en ese caso también podría haber sido hecha por el desarrollador abriendo sus herramientas F12.
fuente
Estoy de acuerdo en que rara vez se debe usar, pero he encontrado un caso de uso poderoso para
eval
.Hay una nueva característica experimental en Firefox llamada asm.js con la que he estado trabajando. Permite compilar un subconjunto limitado del lenguaje Javascript en código nativo. Sí, esto es muy asombroso, pero tiene limitaciones. Puede pensar en el subconjunto limitado de Javascript como un lenguaje tipo C incrustado en Javascript. Realmente no está destinado a ser leído o escrito por humanos.
Este subconjunto limitado de Javascript no me permite inyectar mi código generado en tiempo de ejecución en el código compilado una vez que se ha compilado.
He escrito un código que permite al usuario escribir, en notación familiar, una expresión matemática y convertirlo sobre la marcha en código asm.js. A menos que quiera que el código sea procesado en el lado del servidor (que no lo hago),
eval
es la única herramienta que me permite tener el código resultante procesado por el navegador en tiempo real.fuente
Como lo señalaron otros, lo más importante cuando se trabaja
eval
es mantenerlo a salvo. Para eso, desea hacer una verificación exhaustiva de los argumentos y mantenereval
el código simple, ya que generalmente es mucho más difícil mantener y asegurar el código generado en tiempo de ejecución.Dicho esto, disfruto usarlo
eval
para dos tipos de cosas (aunque probablemente haya alternativas mejores y menos malvadas):eval
es una forma de "código de almacenamiento en caché explícito", se puede utilizar para mejorar el rendimiento. Tenga en cuenta que los optimizadores siempre se mejoran, pero simplemente no hay garantía de lo que pueden hacer por usted. Al hacer las cosas explícitas en el código, en realidad puede ayudar al optimizador a tomar decisiones más inteligentes.Este enfoque de iterador de objeto precompilado , por ejemplo, muestra claros beneficios de rendimiento cuando se usa
eval
para la iteración de propiedad de objeto. También muestra los inicios de un poderoso sistema de tipos que puede proporcionar una comprobación de restricciones implícita y mucho más, a un costo bajo o nulo.Muchos desarrolladores experimentados de Javascript probablemente señalarían que esto es un agujero de conejo, ya que, si comienzas a escribir Javascript de esta manera, esencialmente cambias la forma en que usas el idioma. Sin embargo, eso podría no ser necesariamente algo malo para quienes disfrutan de Javascript, pero también les faltan características fundamentales del lenguaje que solo se pueden lograr cambiando la forma en que usamos el lenguaje en sí.
fuente
Tengo una situación en la que eval parece ser el camino a seguir, evaluando una cadena y devolviendo una variable existente cuyo nombre es el mismo que la cadena.
Tengo varias tablas: table1ResultsTable, table2ResultsTable, tableNResultsTable. Tengo variables configuradas con los mismos nombres, que son objetos de tabla de datos jQuery. Los uso para configurar las tablas y llamar a las funciones de tabla de datos de jQuery en ellas.
Cada tabla tiene asignada class = "resultsTable". Ahora, necesito obtener la variable cuando se hace clic en la tabla. Estoy haciendo esto:
Así que obtengo el ID de la tabla en la que se hizo clic en la celda, que tiene el mismo nombre que la variable de objeto de tabla de datos correspondiente. Si alguien tiene una sugerencia para una mejora, me gustaría saberlo.
fuente
event.target.parentElement.parentElement.parentElement
es horrible. Además, esperaría que la llamada de evaluación genere un error de "error de referencia: [id] no está definido", a menos que esté usando deliberadamente identificables evaluables (que están rotos, incorrectos y pueden causar que ocurran cosas extrañas si finaliza hasta generar identificadores duplicados).document.getElementById(ID).MySpecialProperty = MYSPECIALPROPERTYVALUE
(por no decir que es genial tampoco, pero es mejor que eval). Como señala Eric Lippert, "cada objeto en JScript ya es una tabla de búsqueda".