我正在尝试执行与Google Analytics正在执行的操作类似的操作.我想将函数名称和参数一起推送到数组中,然后执行函数名称和参数.
例如:
var _test = _test || [];
_test.push(['setName', 'Todd']);
Run Code Online (Sandbox Code Playgroud)
并在此处执行setName:
var widget = function () {
function _private_setName(a) {
console.log(a);
}
return{
setName:_private_setName
};
}();
console.log(_test);
Run Code Online (Sandbox Code Playgroud)
_test包含函数名称和参数,但是如何执行该函数?
你必须迭代数组.每个内部数组的第一个元素是方法名称,您可以使用括号表示法来访问对象的方法.要将剩余元素作为参数传递给方法,请使用.apply.
例:
if (window._test) {
for (var i = 0; i < _test.length; i++) {
var method = _test[i].shift(); // this modifies the inner array!
widget[method].apply(widget, _test[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
当然,您应该添加一些检查,以便尝试调用不存在的方法.
为了使这个"模式"真正起作用,你还必须在加载脚本后_test.push正确处理调用.就像现在一样,在加载脚本之后添加到数组的任何元素都将被忽略.在使用具有方法的对象处理现有数组之后,
一种解决方案是替换.既然现在存在,我们可以立即执行函数调用.对于调用代码,接口不会更改._test_test.pushwidget
// iterate over _test and process data
window._test = { // overwrite _test
push: function(cmd) {
var method = cmd.shift();
widget[method].apply(widget, cmd);
}
};
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这只有在_test全局的情况下才有效.我认为在Google Analytics中,_gaq也必须是全球性的.
这种方法的好处在于你没有等到widget准备就绪.缺点可能是代码不是很清楚只是等待脚本加载然后进行"正常"方法调用.
那么,你何时会使用其中一个?就个人而言,我会选择简单地等待脚本加载,例如
loadScript('scripturl', function() {
// script is ready, do stuff
});
Run Code Online (Sandbox Code Playgroud)
但是,有些情况下您不能等到加载脚本.例如,如果您想要跟踪用户互动(Google Analytics的功能).如果您还想动态包含脚本,即scriptHTML中没有标记,则必须使用某种形式的命令队列.