0

javascript変数の文字列としてメソッドの名前があり、変数への呼び出しの結果を取得したいと思います:

var myMethod = "methodToBeCalled";
var result;
eval("result = "+myMethod+"();")

これは機能し、問題はありません。しかし、このコードは Google Closure Compiler では受け入れられません。どのように変更すれば動作するようになりますか? ありがとう!

編集:

メソッドの名前がオブジェクトの内部にある場合、提案されたソリューションは機能しないようです。たとえば、次のようになります。

var myFunction = function () { return "foo!" }
var myObject = {
    itsMethod: function() { return "foo!" }
};
...
var fstMethodToCall = "myFunction"
var sndMethodToCall = "myObject.itsMethod";
...
window[fstMethodToCall](); // foo!
window[sndMethodToCall](); // undefined
4

3 に答える 3

2

ある種のネストされたスコープにいないと仮定して、試してください:

var result = window['methodToBeCalled']();

また

var myMethod = 'methodToBeCalled';
var result = window[myMethod]();

eval を実行せずに、文字列仕様に基づいて任意の深さの任意の関数を実行するには:

var SomeObject = {
    level1: {
        level2: {
            someFunc: function () {
                console.log('hello');
            }
        }
    }
};

var target = 'SomeObject.level1.level2.someFunc';

var obj;
var split = target.split('.');
for (var i = 0; i < split.length; i++) {
    obj = (obj || window)[split[i]];
}

obj();
于 2012-04-27T17:31:15.903 に答える
2

インデクサー表記を使用できます。

result = window[myMethod]();
于 2012-04-27T17:31:31.953 に答える
1

Closure Compiler は 'eval' を禁止していません。都合がよければ引き続き使用できますが、コンパイラは eval ステートメントで何が起こっているのかを理解しようとせず、eval が "安全":

function f(x, y) {
  alert(eval("y")); // fails: hidden reference to "y"
  alert(eval('"'+x+'"'));   // might be valid
}
f('me', 'you');

コンパイラは、この関数を最適化するときに、"y" を削除して、remain パラメータの名前を変更しようとします。これは、「y」が存在しないため、失敗する最初の評価になります。2 番目の評価では、アラート「me」が正しく表示されます。

そのため、SIMPLE 最適化では、eval を使用してグローバル変数とオブジェクト プロパティを参照できます。これらは名前が変更されたり削除されたりしないためです (ただし、ローカル変数は削除されません)。

ADVANCED 最適化では、コンパイラがグローバル変数とローカル変数を削除して名前を変更しようとするため、少し複雑です。したがって、保持する必要がある値をエクスポートする必要があります。これは、文字列を使用して他の方法で名前を参照しようとする場合にも当てはまります。

var methodName = "myMethod";
(window[methodName])()

また

var methodName = "myMethod";
eval(methodName+"()")

コンパイラは、「methodName」が関数への参照であるかどうかを判断しようとはしません。以下は、ADVANCED モードのエクスポートの簡単な例です。

window['myMethod'] = myMethod;

代入は 2 つのことを行います。それがなければ削除される場合に myMethod 関数を保持し、文字列を使用してプロパティに代入することで固定の名前を付けます。ローカル値を参照する必要がある場合は、少し工夫して Function コンストラクターを使用する必要があります。ローカルを評価できる最初の例の "f" の定義:

var f = new Function("x", "y", "alert(eval('y')); alert(eval('\"' + x + '\"'));");

このページは役に立つかもしれません:

https://developers.google.com/closure/compiler/docs/limitations

于 2012-04-28T15:34:27.747 に答える