1

I am trying to do something similar to what Google Analytics is doing. I want to push a function name along with parameters into an array and then execute the function name along with the parameter.

For example:

    var _test = _test || [];
    _test.push(['setName', 'Todd']);

And execute setName in here:

var widget = function () {

    function _private_setName(a) {
        console.log(a);
    }

    return{
       setName:_private_setName
    };  
}();

console.log(_test);

_test contains the function name and parameter, but how can i execute the function?

4

2 回答 2

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

当然,您应该添加一些检查,以便尝试调用不存在的方法。

要使这种“模式”真正起作用,您还必须在脚本加载_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);
    }
};

正如你所看到的,这只有在_test全局的情况下才有效。我认为在 Google Analytics 中,_gaq也必须是全球性的。


这种方法的好处是您不必等到widget准备好。一个缺点可能是代码不是很清楚,只是等待脚本加载然后进行“正常”方法调用。

那么,你什么时候会使用其中一种呢?就我个人而言,我会选择简单地等到脚本加载完毕,例如

loadScript('scripturl', function() {
   // script is ready, do stuff
});

但是,在某些情况下,您不能等到脚本加载完毕。例如,如果您想跟踪用户交互(Google Analytics 所做的)。如果您还想动态地包含脚本,即script在 HTML 中没有标签,您必须使用某种形式的命令队列。

于 2013-08-20T09:01:12.483 回答
0
var _test = _test || [];
_test.push(['setName', 'Todd']);
_test.push(['setName', 'Joe']);

for(var i = 0; i < _test.length; i++){
    widget[_test[i][0]](_test[i][1]);
}
于 2013-08-20T09:04:23.700 回答