动态取代不在全局范围内的函数

时间:2011-04-28 03:40:19

标签: javascript jquery syntax

我有一个基于特定场景的脚本,可能需要取代函数以在最终调用原始函数之前进行一些处理。 (参见“'overriding' Javascript Function”)

我可以通常使用这个 - 这是使用jQuery插件Tinyscrollbar的基本示例(不是我想要的应用程序,只是简单快速的说明):

(function ($) {
    // Snip..

    function initalize() {
        oSelf.update();
        setEvents();
        return oSelf;
    }

    // Snip..

    function setEvents() {

        (function () {
            var oldInit = wheel;

            wheel = function (oEvent) {
                console.log('Intercept');
                oldInit(oEvent);
            }
        })();

        // Original event code, irrelevant to question
    }

    function wheel(oEvent) {
        // Actual function, related to using the mousewheel
    }

})(jQuery);

当我滚动鼠标滚轮时,控制台会打印“拦截”,滚动条会按原定义移动。精彩!

但是,函数名称是硬编码的,并不存在于全局范围内,因此window []不可用(我喜欢)。是否有任何可能的黑魔法组合,'新函数()'和/或其他方式来循环潜在的函数名称列表(可能会根据其他逻辑进行更改)并将其封装在此(或类似于 - 精神)方式?

提前致谢!

1 个答案:

答案 0 :(得分:1)

不幸的是,没有办法枚举或动态访问范围对象中的成员(除了全局范围/窗口对象之外)

所以你需要稍微改写你的代码。不要在外部函数中使用自由浮动函数,而是使用带有方法的对象。这样可以更容易地替换这些方法。

如果在开始将其分配为事件处理程序或其他任何内容后修改函数,则会有一些额外的棘手问题。如果碰巧在这些函数周围使用某种bind()包装器,那么行为的正确性将在很大程度上取决于bind()函数。

具体来说,如果您希望替换方法追溯性地成为为其分配的任何事件处理程序或回调调用的方法,那么您将需要使用带有上下文对象和字符串的bind()包装器。函数名称而不是上下文对象和函数引用。 (并确保bind()不会提前解析该字符串以在每次调用时削减一些ms。)

如果不想要追溯行为,你仍然必须确保你没有一些bind() - 原版方法的版本浮动并且在你的替换发生后仍然用于新的回调