JavaScript将函数和参数推送到数组并执行?

Alo*_*ius 1 javascript

我正在尝试执行与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包含函数名称和参数,但是如何执行该函数?

Fel*_*ing 6

你必须迭代数组.每个内部数组的第一个元素是方法名称,您可以使用括号表示法来访问对象的方法.要将剩余元素作为参数传递给方法,请使用.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中没有标记,则必须使用某种形式的命令队列.