Pregunta ¿Hay alguna manera de crear una función a partir de una cadena con javascript?


Por ejemplo;

var s = "function test(){
  alert(1);
}";

var fnc = aMethod(s);

Si esta es la cadena, quiero una función llamada fnc. Y fnc(); aparece la pantalla de alerta.

eval("alert(1);") no resuelve mi problema


73
2017-10-04 15:10


origen


Respuestas:


Agregué una prueba jsperf para 4 formas diferentes de crear una función a partir de una cadena:

  • Usando RegExp con la clase de Función

    var func = "function (a, b) { return a + b; }".parseFunction();

  • Usar la clase de función con "retorno"

    var func = new Function("return " + "function (a, b) { return a + b; }")();

  • Usando el constructor oficial de funciones

    var func = new Function("a", "b", "return a + b;");

  • Usando Eval

    eval("var func = function (a, b) { return a + b; };");

http://jsben.ch/D2xTG

2 muestras de resultados: enter image description here enter image description here


35
2018-01-18 15:16



Una mejor manera de crear una función a partir de una cadena es mediante el uso de Function:

var fn = Function("alert('hello there')");
fn();

Esto tiene como ventaja / desventaja que las variables en el alcance actual (si no global) no se aplican a la función recién construida.

Pasar argumentos también es posible:

var addition = Function("a", "b", "return a + b;");
alert(addition(5, 3)); // shows '8'

159
2017-10-04 15:16



Estás muy cerca.

//Create string representation of function
var s = "function test(){  alert(1); }";

//"Register" the function
eval(s);

//Call the function
test();

Aquí está un violín de trabajo.


36
2017-10-04 15:13



Sí, usando Function es una gran solución, pero podemos ir un poco más allá y preparar un analizador universal que analice cadenas y las convierta en funciones de JavaScript reales ...

if (typeof String.prototype.parseFunction != 'function') {
    String.prototype.parseFunction = function () {
        var funcReg = /function *\(([^()]*)\)[ \n\t]*{(.*)}/gmi;
        var match = funcReg.exec(this.replace(/\n/g, ' '));

        if(match) {
            return new Function(match[1].split(','), match[2]);
        }

        return null;
    };
}

ejemplos de uso:

var func = 'function (a, b) { return a + b; }'.parseFunction();
alert(func(3,4));

func = 'function (a, b) { alert("Hello from function initiated from string!"); }'.parseFunction();
func();

aquí es jsfiddle


13
2017-11-13 20:37



Nombres de funciones dinámicas en JavaScript

Utilizando Function

var name = "foo";
// Implement it
var func = new Function("return function " + name + "(){ alert('hi there!'); };")();
// Test it
func();
// Next is TRUE
func.name === 'foo'

Fuente: http://marcosc.com/2012/03/dynamic-function-names-in-javascript/

Utilizando eval

var name = "foo";
// Implement it
eval("function " + name + "() { alert('Foo'); };");
// Test it
foo();
// Next is TRUE
foo.name === 'foo'

Utilizando sjsClass

https://github.com/reduardo7/sjsClass

Ejemplo

Class.extend('newClassName', {
    __constructor: function() {
        // ...
    }
});

var x = new newClassName();
// Next is TRUE
newClassName.name === 'newClassName'

11
2017-12-09 14:49



Esta técnica puede ser en última instancia equivalente al método eval, pero quería agregarlo, ya que podría ser útil para algunos.

var newCode = document.createElement("script");

newCode.text = "function newFun( a, b ) { return a + b; }";

document.body.appendChild( newCode );

Esto es funcionalmente como agregar este elemento <script> al final de su documento, por ejemplo:

...

<script type="text/javascript">
function newFun( a, b ) { return a + b; }
</script>

</body>
</html>

5
2018-01-19 06:41



Utilizar el new Function() con un regreso dentro y ejecutarlo de inmediato.

var s = `function test(){
  alert(1);
}`;

var new_fn = new Function("return " + s)()
console.log(new_fn)
new_fn()


1
2018-01-27 02:16



Un ejemplo con argumentos dinámicos:

let args = {a:1, b:2}
  , fnString = 'return a + b;';

let fn = Function.apply(Function, Object.keys(args).concat(fnString));

let result = fn.apply(fn, Object.keys(args).map(key=>args[key]))

0
2017-10-30 01:16