¿Estas dos funciones hacen lo mismo entre bastidores? (en funciones de declaración única)
var evaluate = function(string) {
return eval('(' + string + ')');
}
var func = function(string) {
return (new Function( 'return (' + string + ')' )());
}
console.log(evaluate('2 + 1'));
console.log(func('2 + 1'));
javascript
function
optimization
eval
qwertymk
fuente
fuente
new
considera en esta discusión?Function
implícitamente instancia unfunction object
. La exclusiónnew
no cambiará el código en absoluto. Aquí hay un jsfiddle que demuestra que: jsfiddle.net/PcfG8Respuestas:
No, son no lo mismo.
eval()
evalúa una cadena como una expresión de JavaScript dentro del alcance de ejecución actual y puede acceder a variables locales.new Function()
analiza el código JavaScript almacenado en una cadena en un objeto de función, que luego se puede llamar. No puede acceder a las variables locales porque el código se ejecuta en un ámbito separado.Considere este código:
function test1() { var a = 11; eval('(a = 22)'); alert(a); // alerts 22 }
Si
new Function('return (a = 22);')()
se usara, la variable locala
conservaría su valor. Sin embargo, algunos programadores de JavaScript, como Douglas Crockford, creen que ninguno de los dos debe usarse a menos que sea absolutamente necesario , y evaluar / usar elFunction
constructor en datos que no son de confianza es inseguro e imprudente.fuente
new Function(code)
es lo mismoeval('(function(){'+code+'})()')
o es un contexto de ejecución completamente nuevo?eval('(function(){'+code+'})')
, que devolvería un objeto de función. Según MDN , "Las funciones creadas con el constructor de funciones no crean cierres para sus contextos de creación; siempre se ejecutan en el contexto de la ventana (a menos que el cuerpo de la función comience con una declaración" use estricto ", en cuyo caso el contexto no está definido) . "No.
En su actualización, las llamadas a
evaluate
yfunc
producen el mismo resultado. Pero, definitivamente, no están "haciendo lo mismo entre bastidores". Lafunc
función crea una nueva función, pero luego la ejecuta inmediatamente, mientras que laevaluate
función simplemente ejecuta el código en el acto.De la pregunta original:
var evaluate = function(string) { return eval(string); } var func = function(string) { return (new Function( 'return (' + string + ')' )()); }
Estos te darán resultados muy diferentes:
evaluate('0) + (4'); func('0) + (4');
fuente
return eval('(' + string + ')');
entonces, arrojarían los mismos resultados.new Function
crea una función que se puede reutilizar.eval
simplemente ejecuta la cadena dada y devuelve el resultado de la última declaración. Su pregunta está equivocada cuando intentó crear una función contenedora que usa Function para emular una evaluación.¿Es cierto que comparten algún código detrás de las cortinas? Sí, muy probablemente. ¿Exactamente el mismo código? Claro que no.
Por diversión, aquí está mi propia implementación imperfecta usando eval para crear una función. ¡Espero que arroje algo de luz sobre la diferencia!
function makeFunction() { var params = []; for (var i = 0; i < arguments.length - 1; i++) { params.push(arguments[i]); } var code = arguments[arguments.length - 1]; // Creates the anonymous function to be returned // The following line doesn't work in IE // return eval('(function (' + params.join(',')+ '){' + code + '})'); // This does though return eval('[function (' + params.join(',')+ '){' + code + '}][0]'); }
La mayor diferencia entre esta y la nueva función es que la función no tiene un ámbito léxico. Entonces no tendría acceso a las variables de cierre y la mía sí.
fuente
arguments.slice()
lugar del bucle for? O si los argumentos no es un verdadero arsenal,[].slice.call(arguments, 1)
.Solo quiero señalar alguna sintaxis utilizada en los ejemplos aquí y lo que significa:
var func = function(string) { return (new Function( 'return (' + string + ')' )()); }
observe que la función (...) () tiene el "()" al final. Esta sintaxis hará que func ejecute la nueva función y devuelva la cadena, no una función que devuelva cadena, pero si usa lo siguiente:
var func = function(string) { return (new Function( 'return (' + string + ')' )); }
Ahora func devolverá una función que devuelve una cadena.
fuente
Si quiere decir, dará los mismos resultados, entonces sí ... pero solo evaluar (también conocido como "evaluar esta cadena de JavaScript") sería mucho más simple.
EDITAR Abajo:
Es como decir ... ¿estos dos problemas matemáticos son iguales?
1 + 1
1 + 1 + 1 - 1 + 1 - 1 * 1/1
fuente
Function
objeto probablemente almacena la cadena en una variable de miembro privadaeval
cuando se invoca la función.En ese ejemplo, los resultados son los mismos, sí. Ambos ejecutan la expresión que pasas. Eso es lo que los hace tan peligrosos.
Pero hacen cosas diferentes detrás de la esencia. El que implica
new Function()
, detrás de escena, crea una función anónima a partir del código que proporcionas, que se ejecuta cuando se invoca la función.El JavaScript que le pasa no se ejecuta técnicamente hasta que invoca la función anónima. Esto contrasta con lo
eval()
que ejecuta el código de inmediato y no genera una función basada en él.fuente
Does the Function() one use another stack call level than eval?
: Asumiría que sí, porqueeval()
no crea una función a partir de su entrada, simplemente la ejecuta.new Function()
crea una nueva función, que luego invoca.