有没有一种方法可以这样调用这个javascript函数?

有没有一种方法可以这样调用这个javascript函数?,javascript,Javascript,我希望能够调用类似item_edit.say hello的函数,该函数在窗口对象上作为字符串传递(如下面的最后一行): var弧={view:{item_edit:{}; arc.view.item\u编辑={ 打招呼:函数(){ 警报(‘你好’); } } var f_name='say_hello'; var g_name='item_edit.say_hello'; var str=window.arc.view.item_edit[f_name]();// 这个怎么样: var str2

我希望能够调用类似item_edit.say hello的函数,该函数在窗口对象上作为字符串传递(如下面的最后一行):

var弧={view:{item_edit:{};
arc.view.item\u编辑={
打招呼:函数(){
警报(‘你好’);
}
}
var f_name='say_hello';
var g_name='item_edit.say_hello';
var str=window.arc.view.item_edit[f_name]();// 这个怎么样:

var str2 = eval('window.arc.view.' + g_name + '()');

这里有一种方法可以使用
.reduce()

您需要为较旧的浏览器添加垫片,如果需要,还需要引入安全检查


如果您经常这样做,我会将该函数添加到您的库中,以便您可以重用它

function keyToObj(obj, key) {
    return obj[key];
}
然后像这样使用它:

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

正如所指出的,当使用这种方法时,执行函数的
值存在问题

为了解决这个问题,我们可以制作另一个专门适合方法调用的版本

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

我们可以进一步增强返回的函数,以检查
值是否为默认值,如果不是,则使用提供的值。

当然。Google闭包库在其
goog中执行类似操作。在未经编译器优化时提供
函数

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

返回当前时间戳。

您需要解析字符串,并使用元素遍历循环中的对象。从
g_name.split('.')
开始,然后迭代数组。为什么在str2行的窗口前面有一个句点?或者使用eval“eval('window.arc.view.+g_name+'()”)“别管解析字符串了,我甚至不能解析这个问题……eval不是‘邪恶的’。它是完全有效的javascript,几乎在所有库中都使用(因此可能在web的大多数页面上)。当然,它有性能问题,但大多数javascript都不是时间关键型的。基于对互联网趣闻轶事的教条式坚持而将语言的各个方面一笔勾销的思维方式对现代软件的完整性的损害要大得多。告诉人们使用eval将引导他们面对自己无法解决的问题。这就是为什么eval是邪恶的。@JamesGaunt,允许灵活的序列化和反序列化以及动态代码,而不放弃可分解的安全性。这表明,你可以有你的蛋糕安全明智的,吃它了。“整个语言的设计都考虑到了安全计算;这主要是通过严格遵守面向对象的计算模型来实现的,该模型的纯形式具有支持安全计算的属性……使软件组件能够相互协作,即使它们彼此不完全信任。”@MikeSamuel:很清楚,我不主张在这里使用
eval
。我只是反对对
eval
的下意识反应。我对他们的尊重与我对“您应该完全使用jQuery”评论的尊重是一样的。:-)@用户1689607,我想我们同意了。我的经验法则是,如果您有一个来自您信任的源的Javascript字符串,并且需要它绑定到当前范围内的变量,那么使用
eval
。相反,如果您拥有的不是JavaScript字符串,或者不是来自可信源,或者不应该绑定到当前范围内的变量,那么不要使用
eval
。我认为如果您使用它来调用OP中的方法,那么
this
值将是错误的。
var str2 = g_name.split('.').reduce(keyToMethod, window.arc.view)();
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);
}
callDotted(window, 'Date.now', [])