¿Por qué usar la función de evaluación de JavaScript es una mala idea?

534

La función eval es una manera poderosa y fácil de generar código dinámicamente, ¿cuáles son las advertencias?

Brian Singh
fuente
92
Don't be eval () por Simon Willison - 24ways.org/2005/dont-be-eval
Brian Singh
55
Como se describe en moduscreate.com/javascript-performance-tips-tricks - (new Function (str)) () es más eficiente que eval (str). Just my 2 cents :)
Grgur
3
aparentemente nueva fcuntion (a) es un 67% más lento que eval (a) en el cromo
lo que es el sueño
para mí las nuevas funciones (a) son 80% más lentas que el último Chrome en osx
john Smith
3
Agregué una función estática, solo para comparar el rendimiento. jsperf.com/eval-vs-new-function/2
Nepoxx

Respuestas:

386
  1. El uso incorrecto de eval abre su código para ataques de inyección

  2. La depuración puede ser más desafiante (sin números de línea, etc.)

  3. el código evaluado se ejecuta más lentamente (no hay oportunidad de compilar / almacenar en caché el código evaluado)

Editar: como señala @Jeff Walden en los comentarios, el n. ° 3 es menos cierto hoy que en 2008. Sin embargo, aunque puede ocurrir un almacenamiento en caché de los scripts compilados, esto solo se limitará a los scripts que se evalúen repetidamente sin ninguna modificación. Un escenario más probable es que está evaluando scripts que han sufrido ligeras modificaciones cada vez y, como tal, no se pueden almacenar en caché. Digamos que ALGUNOS códigos evaluados se ejecutan más lentamente.

Prestaul
fuente
2
@JeffWalden, gran comentario. He actualizado mi publicación, aunque me doy cuenta de que ha pasado un año desde que publicaste. Xnzo72, si calificaste un poco tu comentario (como lo hizo Jeff), entonces podría estar de acuerdo contigo. Jeff señaló la clave: "evaluar la misma cadena varias veces puede evitar la sobrecarga de análisis". Tal como están las cosas, simplemente estás equivocado; # 3 es cierto para muchos escenarios.
Prestaul
77
@Prestaul: Dado que el supuesto atacante puede usar cualquier herramienta de desarrollador para cambiar el JavaScript en el cliente, ¿por qué dice que Eval () abre su código a los ataques de inyección? ¿Ya no está abierto? (Estoy hablando de JavaScript del cliente, por supuesto)
Eduardo Molteni
6060
@EduardoMolteni, no nos importa (y de hecho no podemos evitar) que los usuarios ejecuten js en sus propios navegadores. Los ataques que intentamos evitar son cuando los valores proporcionados por el usuario se guardan, luego se colocan en JavaScript y se evalúan. Por ejemplo, podría establecer mi nombre de usuario en: badHackerGuy'); doMaliciousThings();y si toma mi nombre de usuario, lo concatena en un script y lo evalúa en los navegadores de otras personas, entonces puedo ejecutar cualquier javascript que quiera en sus máquinas (por ejemplo, forzarlos a hacer +1 en mis publicaciones, publicar sus datos en mi servidor, etc.)
Prestaul
3
En general, el n. ° 1 es cierto para muchas, si no la mayoría de las llamadas a funciones. eval () no debe ser seleccionado y evitado por programadores experimentados, solo porque los programadores sin experiencia abusan de él. Sin embargo, los programadores experimentados a menudo tienen una mejor arquitectura en su código, y rara vez se requerirá eval o eval () debido a esta mejor arquitectura.
frodeborli
44
@TamilVendhan Seguro que puedes poner puntos de interrupción. Puede acceder al archivo virtual creado por Chrome para su codificación evadida agregando la debugger;declaración a su código fuente. Esto detendrá la ejecución de su programa en esa línea. Luego, después de eso, puede agregar puntos de interrupción de depuración como si fuera solo otro archivo JS.
Sid
346

eval no siempre es malo. Hay momentos en que es perfectamente apropiado.

Sin embargo, eval es sobreutilizado actualmente e históricamente por personas que no saben lo que están haciendo. Eso incluye a personas que escriben tutoriales de JavaScript, desafortunadamente, y en algunos casos esto puede tener consecuencias de seguridad o, más a menudo, errores simples. Entonces, cuanto más podamos hacer para lanzar un signo de interrogación sobre eval, mejor. Cada vez que usa eval necesita verificar con cordura lo que está haciendo, porque es probable que lo esté haciendo de una manera mejor, más segura y más limpia.

Para dar un ejemplo demasiado típico, para establecer el color de un elemento con una identificación almacenada en la variable 'papa':

eval('document.' + potato + '.style.color = "red"');

Si los autores del tipo de código anterior tuvieran una idea sobre los conceptos básicos de cómo funcionan los objetos JavaScript, se habrían dado cuenta de que se pueden usar corchetes en lugar de nombres de puntos literales, lo que evita la necesidad de evaluar:

document[potato].style.color = 'red';

... que es mucho más fácil de leer y con menos errores.

(Pero entonces, alguien que / realmente / sabía lo que estaba haciendo diría:

document.getElementById(potato).style.color = 'red';

que es más confiable que el viejo truco poco fiable de acceder a elementos DOM directamente desde el objeto del documento).

bobince
fuente
82
Hmm, supongo que tuve suerte cuando aprendí JavaScript por primera vez. Siempre usé "document.getElementById" para acceder al DOM; Irónicamente, solo lo hice en ese momento porque no tenía idea de cómo funcionaban los objetos en JavaScript ;-)
Mike Spross
55
de acuerdo. A veces está bien eval por ejemplo, para las respuestas JSON de servicios web
schoetbi
40
@schoetbi: ¿No deberías usar en JSON.parse()lugar de eval()JSON?
nyuszika7h
44
@bobince code.google.com/p/json-sans-eval funciona en todos los navegadores, al igual que github.com/douglascrockford/JSON-js . Json2.js de Doug Crockford usa eval internamente, pero con cheques. Además, es compatible con el soporte de navegador incorporado para JSON.
Martijn
8
@bobince Hay algo llamado detección de características y polyfills para manejar las bibliotecas JSON faltantes y otras cosas (mira modernizr.com )
MauganRa
37

Creo que es porque puede ejecutar cualquier función de JavaScript desde una cadena. Usarlo hace que sea más fácil para las personas inyectar código falso en la aplicación.

kemiller2002
fuente
55
¿Cuál es la alternativa entonces?
modernos
55
Realmente la alternativa es simplemente escribir código que no lo requiera. Crockford profundiza en esto, y si necesita usarlo, dice que es un error de diseño del programa y necesita ser modificado. En verdad, también estoy de acuerdo con él. JS, por todos sus defectos, es realmente flexible y permite mucho espacio para hacerlo flexible.
kemiller2002
3
No es cierto, la mayoría de los marcos tienen un método para analizar JSON, y si no está usando un marco, puede usar JSON.parse (). La mayoría de los navegadores lo admiten, y si realmente está en apuros, podría escribir un analizador para JSON con bastante facilidad.
kemiller2002
66
No compro este argumento, porque ya es fácil inyectar código falso en una aplicación Javascript. Tenemos consolas de navegador, extensiones de script, etc. Cada código enviado al cliente es opcional para que el cliente lo ejecute.
user2867288
66
El punto es que es más fácil para mí inyectar código en su navegador. Digamos que está utilizando eval en una cadena de consulta. Si lo engaño para que haga clic en un enlace que va a ese sitio con mi cadena de consulta adjunta, ahora he ejecutado mi código en su máquina con el permiso completo del navegador. ¿Quiero registrar todo lo que escribes en ese sitio y enviármelo? Hecho y no hay forma de detenerme porque cuando eval se ejecuta, el navegador le otorga la máxima autoridad.
kemiller2002
27

Me vienen a la mente dos puntos:

  1. Seguridad (pero siempre que genere la cadena para evaluarla usted mismo, esto podría no ser un problema)

  2. Rendimiento: hasta que se desconozca el código a ejecutar, no se puede optimizar. (sobre JavaScript y rendimiento, ciertamente la presentación de Steve Yegge )

xtofl
fuente
99
¿Por qué la seguridad es un problema si el cliente de todos modos podría hacer con nuestro código lo que quiera? Greasemonkey?
Paul Brewczynski
2
@PaulBrewczynski, el problema de seguridad aparece cuando el usuario A guarda su parte del código para ser evalevaluado y luego, ese pequeño fragmento de código se ejecuta en el navegador B del usuario
Felipe Pereira
21

Pasar la entrada del usuario a eval () es un riesgo de seguridad, pero también cada invocación de eval () crea una nueva instancia del intérprete de JavaScript. Esto puede ser un gran recurso.

Andrew Hedges
fuente
27
En los más de 3 años desde que respondí esto, mi comprensión de lo que sucede se ha profundizado, digamos. Lo que realmente sucede es que se crea un nuevo contexto de ejecución. Ver dmitrysoshnikov.com/ecmascript/chapter-1-execution-contexts
Andrew Hedges el
20

En general, solo es un problema si está pasando la entrada del usuario eval.

Mark Biek
fuente
16

Principalmente, es mucho más difícil de mantener y depurar. Es como una goto. Puede usarlo, pero hace que sea más difícil encontrar problemas y más difícil para las personas que pueden necesitar hacer cambios más adelante.

Brian
fuente
Eval se puede usar para sustituir las características de metaprogramación que faltan, como las plantillas. Me gusta mucho más el generador compacto que la lista interminable de funciones sobre funciones.
weaknespase
Siempre y cuando la cadena no provenga del usuario o esté limitada al navegador, puede hacerlo. JavaScript tiene mucho poder de metaprogramación usando cosas como cambiar prototipos, obj [miembro], Proxy, json.parse, ventana, funciones de decorador (adverbios) donde newf = decorator (oldf), función de orden superior como Array.prototype.map (f) , pasar argumentos a otras funciones, argumentos de palabras clave a través de {}. ¿Me puede decir un caso de uso donde no puede hacer esto en lugar de evaluar?
aoeu256
13

Una cosa a tener en cuenta es que a menudo puede usar eval () para ejecutar código en un entorno de otro modo restringido: los sitios de redes sociales que bloquean funciones específicas de JavaScript a veces se pueden engañar al dividirlos en un bloque eval.

eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');

Entonces, si está buscando ejecutar algún código JavaScript donde de otra manera no se permitiría ( Myspace , lo estoy mirando ...), entonces eval () puede ser un truco útil.

Sin embargo, por todas las razones mencionadas anteriormente, no debe usarlo para su propio código, donde tiene el control completo: simplemente no es necesario, y es mejor relegarlo al estante de 'trucos de JavaScript difíciles'.

Matt Lohkamp
fuente
1
Simplemente actualizando el código anterior ... --¡hi! - debe estar entre comillas, ya que es una cadena. eval ('al' + 'er' + 't (' + '"¡Hola!"' + ')');
Mahesh
2
[]["con"+"struc"+"tor"]["con"+"struc"+"tor"]('al' + 'er' + 't(\'' + 'hi there!' + '\')')()
Konrad Borowski el
44
¡Vaya, había sitios de redes sociales que restringían alert () pero permitían eval () ?!
joshden
12

A menos que permita que eval () sea un contenido dinámico (a través de cgi o input), es tan seguro y sólido como el resto de JavaScript en su página.

Thevs
fuente
Si bien esto es cierto, si su contenido no es dinámico, ¿qué razón hay para utilizar eval para ello? ¡Podrías simplemente poner el código en una función y llamarlo, en cambio!
Periata Breatta
Solo por ejemplo, para analizar el valor de retorno (como JSON, cadenas definidas por el servidor, etc.) que provienen de la llamada Ajax.
Thevs
2
Oh ya veo. Los llamaría dinámicos porque el cliente no sabe de antemano cuáles son, pero ahora entiendo a qué se refiere.
Periata Breatta
7

Junto con el resto de las respuestas, no creo que las declaraciones de evaluación puedan tener una minimización avanzada.

Paul Mendoza
fuente
6

Es un posible riesgo de seguridad, tiene un alcance de ejecución diferente y es bastante ineficiente, ya que crea un entorno de secuencias de comandos completamente nuevo para la ejecución del código. Vea aquí para más información: eval .

Sin embargo, es bastante útil y se usa con moderación para agregar una gran cantidad de buenas funciones.

Tom
fuente
5

A menos que esté 100% seguro de que el código que se está evaluando proviene de una fuente confiable (generalmente su propia aplicación), entonces es una forma segura de exponer su sistema a un ataque de secuencias de comandos entre sitios.

John Topley
fuente
1
Solo si su seguridad del lado del servidor apesta. La seguridad del lado del cliente no tiene sentido.
doubleOrt
5

Sé que esta discusión es antigua, pero realmente me gusta esto enfoque de Google y quería compartir ese sentimiento con otros;)

La otra cosa es que cuanto mejor obtienes, más tratas de entender y, finalmente, simplemente no crees que algo es bueno o malo solo porque alguien lo dijo :) Este es un video muy inspirador que me ayudó a pensar más por mí mismo :) Las BUENAS PRÁCTICAS son buenas, pero no las uses sin pensar :)

op1ekun
fuente
1
Si. He encontrado, hasta ahora al menos en Chrome, un caso de uso que parece ser más eficiente. Ejecute un RAF que evalúa una cadena en una variable dada cada iteración. Use un setInterval para establecer solo cosas orientadas gráficamente como establecer transformaciones, etc. en esa cadena. He intentado muchos otros enfoques, como recorrer las funciones en una matriz o usar una variable para establecer solo transformaciones para los elementos que se cambian, pero hasta ahora esto parece ser más eficiente. Cuando se trata de animación, la prueba de banco más auténtica son tus ojos.
jdmayfield
5

No es necesariamente tan malo siempre que sepa en qué contexto lo está utilizando.

Si su aplicación está usando eval()para crear un objeto de algún JSON que ha regresado de un XMLHttpRequest a su propio sitio, creado por su código confiable del lado del servidor, probablemente no sea un problema.

El código JavaScript del lado del cliente no confiable no puede hacer tanto de todos modos. Siempre que lo que está ejecutando eval()proviene de una fuente razonable, está bien.

MarkR
fuente
3
¿No está usando eval más lento que simplemente analizar el JSON?
Brendan Long
@Qix: ejecutar esa prueba en mi navegador (Chrome 53) muestra eval como algo más rápido que analizar .
Periata Breatta
@PeriataBreatta Huh, extraño. Me pregunto porque. En ese momento comenté que ese no era el caso. Sin embargo, no es raro que Chrome obtenga extraños aumentos de rendimiento en ciertas áreas del tiempo de ejecución de una versión a otra.
Qix - MONICA FUE MALTRATADA el
Un pequeño hilo viejo aquí, pero por lo que he leído, sin afirmar que lo rastreé yo mismo, JSON. De hecho, eval es su entrada en la etapa final. Entonces, en cuanto a eficiencia, requiere más trabajo / tiempo. Pero en cuanto a la seguridad, ¿por qué no simplemente analizar? eval es una herramienta asombrosa. Úselo para cosas que no tienen otra manera. Para pasar funciones a través de JSON, hay una manera de hacerlo sin eval. Ese segundo parámetro en JSON.stringify le permite ejecutar una devolución de llamada que puede verificar a través de typeof si es una función. Luego obtenga la función .toString (). Hay algunos buenos artículos sobre esto si busca.
jdmayfield
4

Reduce en gran medida su nivel de confianza sobre la seguridad.

David Plumpton
fuente
4

Si desea que el usuario ingrese algunas funciones lógicas y evalúe AND Y, entonces la función de evaluación de JavaScript es perfecta. Puedo aceptar dos cadenas y eval(uate) string1 === string2, etc.

Ian
fuente
También puede usar la función () {}, pero tenga cuidado al usarlos en el servidor a menos que desee que los usuarios se hagan cargo de su servidor jajajaja.
aoeu256
3

Si ve el uso de eval () en su código, recuerde el mantra "eval () is evil".

Esta función toma una cadena arbitraria y la ejecuta como código JavaScript. Cuando el código en cuestión se conoce de antemano (no se determina en tiempo de ejecución), no hay razón para usar eval (). Si el código se genera dinámicamente en tiempo de ejecución, a menudo hay una mejor manera de lograr el objetivo sin eval (). Por ejemplo, simplemente usar la notación de corchetes para acceder a las propiedades dinámicas es mejor y más simple:

// antipattern
var property = "name";
alert(eval("obj." + property));

// preferred
var property = "name";
alert(obj[property]);

El uso eval()también tiene implicaciones de seguridad, ya que podría estar ejecutando código (por ejemplo, procedente de la red) que ha sido alterado. Este es un antipatrón común cuando se trata con una respuesta JSON de una solicitud de Ajax. En esos casos, es mejor usar los métodos integrados de los navegadores para analizar la respuesta JSON para asegurarse de que sea segura y válida. Para navegadores que no admitenJSON.parse() forma nativa, puede usar una biblioteca de JSON.org.

También es importante recordar que pasar cadenas a setInterval(), setTimeout()y el Function()constructor es, en su mayor parte, similar al uso eval()y, por lo tanto, debe evitarse.

Detrás de escena, JavaScript todavía tiene que evaluar y ejecutar la cadena que pasa como código de programación:

// antipatterns
setTimeout("myFunc()", 1000);
setTimeout("myFunc(1, 2, 3)", 1000);

// preferred
setTimeout(myFunc, 1000);
setTimeout(function () {
myFunc(1, 2, 3);
}, 1000);

El uso del nuevo constructor Function () es similar a eval () y debe abordarse con cuidado. Podría ser una construcción poderosa, pero a menudo se usa mal. Si absolutamente debes usareval() , puede considerar usar una nueva función () en su lugar.

Hay un pequeño beneficio potencial porque el código evaluado en la nueva función () se ejecutará en un ámbito de función local, por lo que las variables definidas con var en el código que se evalúa no se convertirán en globales automáticamente.

Otra forma de prevenir los globales automáticos es envolver la eval()llamada en una función inmediata.

12345678
fuente
¿Puede sugerirme cómo podría evaluar un nombre de variable dinámica local de función sin eval? Las funciones de evaluación (y similares) son los últimos recursos en la mayoría de los idiomas que las contienen, pero a veces es necesario. En el caso de obtener el nombre de una variable dinámica, ¿hay alguna solución más segura? En cualquier caso, javascript en sí no es para la seguridad real (el lado del servidor es obviamente la defensa principal). Si está interesado, aquí está mi caso de uso de eval, que me encantaría cambiar: stackoverflow.com/a/48294208
Regular Joe
2

Además de los posibles problemas de seguridad si está ejecutando código enviado por el usuario, la mayoría de las veces hay una mejor manera que no implica volver a analizar el código cada vez que se ejecuta. Las funciones anónimas o las propiedades de objeto pueden reemplazar la mayoría de los usos de eval y son mucho más seguras y rápidas.

Matthew Crumley
fuente
2

Esto puede convertirse en un problema ya que la próxima generación de navegadores sale con un poco de compilador de JavaScript. El código ejecutado a través de Eval puede no funcionar tan bien como el resto de su JavaScript en estos navegadores más nuevos. Alguien debería hacer algunos perfiles.

Brian
fuente
2

Este es uno de los buenos artículos que hablan sobre eval y cómo no es un mal: http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/

No estoy diciendo que debas salir corriendo y comenzar a usar eval () en todas partes. De hecho, hay muy pocos casos de uso buenos para ejecutar eval (). Definitivamente, existen preocupaciones con respecto a la claridad del código, la capacidad de depuración y, ciertamente, el rendimiento que no deben pasarse por alto. Pero no debe tener miedo de usarlo cuando tiene un caso en el que eval () tiene sentido. Intente no usarlo primero, pero no permita que nadie lo asuste y piense que su código es más frágil o menos seguro cuando eval () se usa adecuadamente.

Amr Elgarhy
fuente
2

eval () es muy poderoso y puede usarse para ejecutar una declaración JS o evaluar una expresión. Pero la pregunta no se trata de los usos de eval (), sino que digamos de alguna manera cómo la cadena que ejecuta con eval () se ve afectada por una parte maliciosa. Al final estarás ejecutando código malicioso. Con el poder viene una gran responsabilidad. Así que úsalo sabiamente si lo estás usando. Esto no se relaciona mucho con la función eval () pero este artículo tiene bastante buena información: http://blogs.popart.com/2009/07/javascript-injection-attacks/ Si está buscando los conceptos básicos de eval () mira aquí: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval

Fi
fuente
2

El motor de JavaScript tiene una serie de optimizaciones de rendimiento que realiza durante la fase de compilación. Algunos de estos se reducen a la capacidad de analizar esencialmente el código estáticamente a medida que se relaja, y predeterminar dónde están todas las declaraciones de variables y funciones, por lo que se necesita menos esfuerzo para resolver los identificadores durante la ejecución.

Pero si el motor encuentra una evaluación (..) en el código, esencialmente tiene que suponer que toda su conciencia de la ubicación del identificador puede ser inválida, porque no puede saber en el momento exacto qué código puede pasarle a evaluación (..) para modificar el alcance léxico, o el contenido del objeto con el que puede pasar para crear un nuevo alcance léxico para ser consultado.

En otras palabras, en el sentido pesimista, la mayoría de esas optimizaciones que haría no tienen sentido si eval (..) está presente, por lo que simplemente no realiza las optimizaciones en absoluto.

Esto lo explica todo.

Referencia:

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#eval

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#performance

hkasera
fuente
Ningún motor de JavaScript no puede encontrar y evaluar el código con una garantía del 100%. Por lo tanto, debe estar listo para ello en cualquier momento.
Jack Giffin
2

No siempre es una mala idea. Tomemos, por ejemplo, la generación de código. Recientemente escribí una biblioteca llamada Hyperbars que cierra la brecha entre virtual-dom y el manillar . Lo hace analizando una plantilla de manillar y convirtiéndola en hiperescrito que posteriormente es utilizado por virtual-dom. El hiperescrito se genera primero como una cadena y, antes de devolverlo, eval()lo convierte en código ejecutable. En eval()esta situación particular he encontrado exactamente lo contrario del mal.

Básicamente de

<div>
    {{#each names}}
        <span>{{this}}</span>
    {{/each}}
</div>

A esto

(function (state) {
    var Runtime = Hyperbars.Runtime;
    var context = state;
    return h('div', {}, [Runtime.each(context['names'], context, function (context, parent, options) {
        return [h('span', {}, [options['@index'], context])]
    })])
}.bind({}))

El rendimiento de eval()no es un problema en una situación como esta porque solo necesita interpretar la cadena generada una vez y luego reutilizar la salida ejecutable muchas veces.

Puedes ver cómo se logró la generación del código si tienes curiosidad aquí .

Wikened
fuente
2

Me atrevería a decir que realmente no importa si usa eval()JavaScript que se ejecuta en navegadores. * (Advertencia)

Todos los navegadores modernos tienen una consola de desarrollador donde puedes ejecutar JavaScript arbitrario de todos modos y cualquier desarrollador semi-inteligente puede mirar tu fuente JS y poner lo que necesiten en la consola de desarrollo para hacer lo que deseen.

* Siempre y cuando los puntos finales de su servidor tengan la validación y desinfección correctas de los valores proporcionados por el usuario, no debería importar lo que se analice y evalúe en su javascript del lado del cliente.

eval()Sin embargo, si tuviera que preguntar si es adecuado para usar en PHP, la respuesta es NO , a menos que incluya en la lista blanca cualquier valor que pueda pasar a su sentencia eval.

Adam Copley
fuente
no solo hay una consola de desarrollo, también puede escribir javascript: código en la barra de URL para construir su propia consola de desarrollo en la página si no hay ninguna, como es el caso en los antiguos navegadores IE y dispositivos móviles.
Dmitry
1

No intentaré refutar nada de lo dicho hasta ahora, pero ofreceré este uso de eval () que (hasta donde yo sé) no se puede hacer de otra manera. Probablemente hay otras formas de codificar esto, y probablemente formas de optimizarlo, pero esto se hace a mano y sin ningún tipo de campanas y silbatos por razones de claridad para ilustrar un uso de eval que realmente no tiene otras alternativas. Es decir: nombres de objeto dinámicamente (o más exactamente) creados mediante programación (en oposición a los valores).

//Place this in a common/global JS lib:
var NS = function(namespace){
    var namespaceParts = String(namespace).split(".");
    var namespaceToTest = "";
    for(var i = 0; i < namespaceParts.length; i++){
        if(i === 0){
            namespaceToTest = namespaceParts[i];
        }
        else{
            namespaceToTest = namespaceToTest + "." + namespaceParts[i];
        }

        if(eval('typeof ' + namespaceToTest) === "undefined"){
            eval(namespaceToTest + ' = {}');
        }
    }
    return eval(namespace);
}


//Then, use this in your class definition libs:
NS('Root.Namespace').Class = function(settings){
  //Class constructor code here
}
//some generic method:
Root.Namespace.Class.prototype.Method = function(args){
    //Code goes here
    //this.MyOtherMethod("foo"));  // => "foo"
    return true;
}


//Then, in your applications, use this to instantiate an instance of your class:
var anInstanceOfClass = new Root.Namespace.Class(settings);

EDITAR: por cierto, no sugeriría (por todas las razones de seguridad señaladas hasta ahora) que base sus nombres de objetos en la entrada del usuario. Sin embargo, no puedo imaginar ninguna buena razón por la que quieras hacer eso. Aún así, pensé en señalar que no sería una buena idea :)

Carnix
fuente
3
esto se puede hacer con el namespaceToTest[namespaceParts[i]], sin necesidad de eval aquí, por lo que la if(typeof namespaceToTest[namespaceParts[i]] === 'undefined') { namespaceToTest[namespaceParts[i]] = {};única diferencia para elelse namespaceToTest = namespaceToTest[namespaceParts[i]];
user2144406
1

Recolección de basura

La recolección de basura de los navegadores no tiene idea de si el código evaluado puede eliminarse de la memoria, por lo que simplemente lo mantiene almacenado hasta que se vuelve a cargar la página. No está mal si sus usuarios solo están en su página en breve, pero puede ser un problema para las aplicaciones web.

Aquí hay un script para demostrar el problema

https://jsfiddle.net/CynderRnAsh/qux1osnw/

document.getElementById("evalLeak").onclick = (e) => {
  for(let x = 0; x < 100; x++) {
    eval(x.toString());
  }
};

Algo tan simple como el código anterior hace que se almacene una pequeña cantidad de memoria hasta que la aplicación muera. Esto es peor cuando el script evadido es una función gigante, y se llama a intervalos.

JD
fuente