我希望能够调用像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是做什么的)。
答案 0 :(得分:1)
不确定。当没有被编译器优化时,Google闭包库在其goog.provide
函数中执行类似的操作。
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', [])
返回当前时间戳。
答案 1 :(得分: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
值是否为默认值,如果不是,则使用提供的值。
答案 2 :(得分:-1)
这个怎么样:
var str2 = eval('window.arc.view.' + g_name + '()');