web-dev-qa-db-ja.com

javascriptを使用して文字列から関数を作成する方法はありますか?

例えば;

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

var fnc = aMethod(s);
_

これが文字列の場合、fncと呼ばれる関数が必要です。そして、fnc();は警告画面をポップします。

eval("alert(1);")は私の問題を解決しません。

89
ymutlu

Stringから関数を作成する4つの異なる方法のjsperfテストを追加しました。

  • FunctionクラスでRegExpを使用する

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

  • 「return」でFunctionクラスを使用する

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

  • 公式の関数コンストラクターを使用する

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

  • Evalを使用する

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

http://jsben.ch/D2xTG

2つの結果サンプル: enter image description hereenter image description here

50
phnah

文字列から関数を作成するより良い方法は、Functionを使用することです:

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

これには、現在のスコープ内の変数(グローバルでない場合)が新しく構築された関数に適用されないという利点/欠点があります。

引数を渡すことも可能です。

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

あなたはかなり近いです。

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

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

//Call the function
test();

作業フィドル です。

38
James Hill

はい、Functionを使用することは優れたソリューションですが、文字列を解析して実際のJavaScript関数に変換するユニバーサルパーサーをもう少し準備して...

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;
    };
}

使用例:

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();

ここ はjsfiddleです

13
Mr. Pumpkin

JavaScriptの動的関数名

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'

ソース: http://marcosc.com/2012/03/dynamic-function-names-in-javascript/

evalを使用する

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

sjsClassを使用する

https://github.com/reduardo7/sjsClass

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

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

この手法は、最終的にはevalメソッドと同等かもしれませんが、一部の人にとっては役に立つかもしれないので、追加したいと思いました。

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

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

document.body.appendChild( newCode );

機能的には、この<script>要素をドキュメントの最後に追加するようなものです。例:

...

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

</body>
</html>
5
David Newberry

new Function()を使用して内部に戻り、すぐに実行します。

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

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

動的な引数の例:

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
brunettdan