1

window オブジェクトで文字列として渡された item_edit.say hello のような関数を呼び出せるようにしたいと思います (次の最後の行のように)。

var arc={ view: { item_edit: {} } };

arc.view.item_edit={
  say_hello: function(){
    alert('hello there');
  }

}

var f_name='say_hello';
var g_name='item_edit.say_hello';

var str=window.arc.view.item_edit[f_name]();  // <- this works
var str2=window.arc.view[g_name]();  // <- this is what I'm interested in; curently doesn't work

これを機能させる方法についてのアイデアはありますか?

thx事前に

編集#1 おそらくevalを実行したくないことを追加する必要があると思いますが、それを見れば見るほど、それが理にかなっている可能性があります(実際、evalが実行されたことです)。

4

3 に答える 3

1

もちろん。goog.provideGoogle クロージャ ライブラリは、コンパイラによって最適化されていない場合、関数内でこのようなことを行います。

function callDotted(obj, path, args) {
  var parts = path ? path.split('.') : [];
  var i, n = parts.length;
  for (i = 0; i < n - 1; ++i) {
    obj = obj[parts[i]];
  }
  var fn = i < n ? obj[parts[i]] : obj;
  return fn.apply(obj, args);
}

Date.now次に、現在のタイムスタンプを返すブラウザで、

callDotted(window, 'Date.now', [])

現在のタイムスタンプを返します。

于 2012-11-08T18:34:33.730 に答える
0

を使用する1つの方法があり.reduce()ます。

var str2 = g_name.split('.').reduce(function(obj, key) {
    return obj[key];
}, window.arc.view);

古いブラウザの場合はシムし、必要に応じて安全性チェックを導入する必要があります。


これを頻繁に行う場合は、ライブラリに関数を追加して、再利用できるようにします。

function keyToObj(obj, key) {
    return obj[key];
}

次に、次のように使用します。

var str2 = g_name.split('.').reduce(keyToObj, window.arc.view);

@MikeSamuelが指摘したように、このアプローチを使用すると、実行される関数の値に問題がありますthis

これを解決するために、メソッド呼び出しに特に適した別のバージョンを作成できます。

function keyToMethod(obj, key, i, arr) {
    return i === arr.length - 1 && typeof obj[key] === "function"
                              ? function() {
                                    return obj[key].apply(obj, arguments);
                                }
                              : obj[key];
}

これで、関数は適切なオブジェクトからメソッドを呼び出す関数を返します。

var str2 = g_name.split('.').reduce(keyToMethod, window.arc.view)();

this返された関数をさらに拡張して、値がデフォルト値であるかどうかを確認し、そうでない場合は提供された値を使用することができます。

于 2012-11-08T18:29:55.227 に答える
-1

これはどう:

var str2 = eval('window.arc.view.' + g_name + '()');
于 2012-11-08T18:26:12.963 に答える