notas adicionales a la publicación Cristian Sánchez'.
Nunca se puede acceder a vars de ámbito local dentro de una 'Evaluación de funciones'.
Veamos la diferencia entre Function y eval.
función Ejemplo:
var f, a = 1;
(function() {
var a = 123;
f = new Function("return a");
})();
console.log(f()) // 1
la función de constructor no se sabe nada sobre el ámbito local, ya que crea un nuevo ámbito aislado debajo de la ventana/Objeto-mundial - no en la posición en la que es - esa es la principal diferencia para eval.
Eval-Ejemplo:
var f, a = 1;
(function() {
var a = 123;
eval("f = function() { return a }");
})();
console.log(f()) // 123
'eval' tiene acceso a los vars locales. Incluso si abarca todo el asunto.
var f, a = 1;
(function() {
var a = 123;
eval("f = (function() { function f() { return a }; return f; })();");
})();
console.log(f()) // still 123
En el siguiente ejemplo f() lanza un error - "a" no está definida en su propia (y global) alcance. El Function-Constructor tiene su propio alcance especial sin conocer nada fuera, excepto su ámbito principal, la ventana/global-object.
delete a;
var f;
(function()
{
var a = 1;
f = new Function("return a");
})();
console.log(f()); // Throws error (a is not defined)
Si desea utilizar VARs locales, pasarlo como parámetros a la función constructor dentro del ámbito interno!
var f, a = 1;
(function() {
var a = 123;
f = new Function("a", "return a");
console.log(f(a)); // passing inner a: result = 123
})();
console.log(f(a)); // passing outer a: result = 1
o
var result, a = 1;
(function() {
var a = 123;
var f = new Function("a", "return a");
result = f(a); // store result in global var
})();
console.log(result); // 123
Puede ejecutar la función directamente con llamada/aplicarán, también (no "nueva" es necesario).
Function('a','b','c', 'console.log(c,b,a)').call(this, 1, 2, 3); // output: 3 2 1
Function('console.log(arguments)').apply(this, [1, 2, 3]); // access through arguments[0-3]
Por cierto, siempre recomiendan, estableciendo el modo estricto, para permitir el correcto comportamiento ES5.
Con el modo estricto, 'this' está (correctamente) indefinido por defecto, hasta que vincula un objeto.
Function('console.log(this)')(); // this is 'window' in sloppy mode
Function('"use strict"; console.log(this)')(); // this is undefined - correct behavior
Si lo desea, puede enlazar 'esto' explícitamente
// bind 'this' to 'window' again
Function('"use strict";console.log(this)').bind(window)();
// bind 'this' to an Object without __proto__
Function('"use strict";console.log(this)').bind(Object.create(null))();
Por supuesto se puede enlazar cualquier/clase objeto de la función de ampliar los objetos.
function SomeClass()
{
this.a = 1;
}
var cls = new SomeClass();
new Function('"use strict"; this.a = 5; this.b = 6;').bind(cls)();
console.log(cls.a); // a = 5 - override property
console.log(cls.b); // b = 6 - appended property
Mismo resultado con llamada directa, sin palabra clave 'nueva'.
function SomeClass()
{
this.a = 1;
}
var cls = new SomeClass();
Function('"use strict"; this.a = 5; this.b = 6; this.foo = function(){console.log("bar")}').call(cls);
console.log(cls.a); // a = 5 - override property
console.log(cls.b); // b = 6 - appended property
console.log(cls.foo()); // bar - appended function
Cada función/clase se crea mediante el constructor de 'Funciones'.
Así que no tiene que escribir "Función" en su código. También puedes usar el constructor-object.
function SomeClass()
{
this.a = 1;
}
var cls = new SomeClass();
SomeClass.constructor("this.a = 2;").call(cls);
cls; // SomeClass {a: 2}, because "SomeClass.constructor" === Function
El uso de 'Función' es positivo, por ejemplo para los juegos, si usted tiene un XMLHttpRequest-Precargador, que carga una gran Javascript-File (5-10 MB scripts de paquetes), mientras que usted quiere mostrar una barra de carga u otra cosa para el usuario, en su lugar carga todo con una secuencia de comandos, mientras que el usuario está esperando cargar la página sin ninguna respuesta visual.
No importa si carga una secuencia de comandos grande mediante una etiqueta de secuencia de comandos o mediante una función una vez al inicio. El motor tiene que cargar el código simple y evaluarlo de cualquier manera. No hay aspectos de seguridad, si su (!) Código proviene de una fuente confiable (su dominio) y usted sabe qué hay dentro.
'Función' y 'eval' solo son incorrectos con código no confiable (cuando otros usuarios influyen en él) o en bucles (lenta ejecución debido a compilación), pero está bien cargar & evaluar sus propios scripts al inicio , si el código es el mismo que en los archivos Javascript externos.
Ver: [Usos legítimos del constructor de funciones] (http://stackoverflow.com/questions/3026089/legitimate-uses-of-the-function-constructor) – CMS
Buen video sobre las funciones de JavaScript http: // developer. yahoo.com/yui/theater/video.php?v=crockonjs-3 – Thomas
@CMS @Thomas, gracias por los enlaces. – c4il