1

我希望能够调用像 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

关于如何让它发挥作用的任何想法?

提前谢谢

编辑#1 我想我应该补充一点,尽管我看的越多,这可能就是不想做 eval ,这可能是有道理的(实际上这就是 eval 要做的事情)。

4

3 回答 3

1

当然。goog.provide当编译器未优化时,Google 闭包库会在其函数中执行类似的操作。

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

这是使用.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 回答