只需通过扩展覆盖jQuery函数?

时间:2014-05-31 12:52:27

标签: javascript jquery

这与另一个SO Q& A Override jQuery functions有关,但不是重复。

从上述问题的答案可以清楚地看出,覆盖jQuery函数的模式是:

(function($){

    // store original reference to the method
    var _old = $.fn.method;

    $.fn.method = function(arg1,arg2){

        if ( ... condition ... ) {
           return  ....
        } else {           // do the default
           return _old.apply(this,arguments);
        }
    };
})(jQuery);


但为什么!?

我已经能够简单地通过在$.extend$.fn.extend内定义与要覆盖的函数同名的函数来覆盖jQuery函数。

考虑一下:

// random example showing jquery function overriding
$.fn.extend({
    hide: function() {
        $(this).css({"color":"red"});
    }
});

$("#test").hide(); // this will actually paint the #test element red!

jsFiddle

我想了解为什么_old.apply(this,arguments)是覆盖jQuery函数的首选方式,如herehere所列。

2 个答案:

答案 0 :(得分:0)

通过浏览原始帖子中提供的引用,模式的摘要可以保持“旧”和“新”方法的可用性吗?

修改,更新

  

抱歉,我不明白这一点。据我所知,对重写方法的引用保存在闭包中的局部变量中   毫无疑问,在关闭之外失败了。你能解释一下“老”吗?   方法仍然可用? -SNag

     

我想理解为什么_old.apply(这个,参数)会是   覆盖jQuery函数的首选方法,如列出here和   here

在上面的第一个链接上使用模式,如果正确解释了部分,则在“自执行匿名函数”中的arguments jquery方法语句中出现test if确定返回值“旧的“或”新“(新包含;覆盖)jquery方法?

,例如,尝试

HTML

<div>abc</div>

js

// See http://www.paulirish.com/2010/duck-punching-with-jquery/ , at
// `First we start off with a self-executing anonymous function,
// that makes a happy closure while remapping jQuery to $:`

// `closure` start
    (function ($) {
        // jquery `.css()`
        var _oldcss = $.fn.css;
        // jquery `.hide()`
        var _oldhide = $.fn.hide;

        // "new" `.css()`
        $.fn.css = function (prop, value) {
            // "new" `.css()` `test`
            if (/^background-?color$/i.test(prop) 
                && value.toLowerCase() === 'burnt sienna') {
                return _oldcss.call(this, prop, '#EA7E5D');
            } else {
                return _oldcss.apply(this, arguments);
            }
        };

        // "new" `.hide()`
        $.fn.hide = function (prop, value) {
            // "new" `.hide()` `test` 
            if (/color/i.test(prop) && /[a-f]|[0-9]/i.test(value)) {
                return $.fn.css.call(this, prop, value);
            } else {
                return _oldhide.apply(this, arguments);
            }
        };
    })(jQuery);
    // `closure` stop

    // and using it...
    // "new" `.css()`
    jQuery(document.body).css('backgroundColor', 'burnt sienna');
    // "old" `.css()`
    $("div").css("color", "yellow");
    // "old" `.hide()`
    $("div").hide(7500, function () {
        // "old" `.css()`
        $(document.body)
            .css({
            "transition": "background 2s",
            "background": "#edd452"
        })
        .find($("div")).show(2500)
        // "new" `.hide()`
        .hide("color", "red")
    });

jsfiddle http://jsfiddle.net/guest271314/5bEe4/

答案 1 :(得分:0)

(function($){

    // store original reference to the method
    // stored locally
    var _old = $.fn.method;

    $.fn.method = function(arg1,arg2){

        if ( ... condition ... ) {
           return  ....
        } else {           // do the default
           // call apply method, in order to pass the this context.
           return _old.apply(this,arguments);
        }
    };
})(jQuery);

在上面的代码中,我们调用了一个匿名函数,我们在其中声明一个局部变量_old。执行此匿名函数时,它会保存_old方法引用并形成closure。 现在,当我们称之为新方法时,即

    $.fn.method = function(arg1,arg2){
       if ( ... condition ... ) {
           return  ....
        } else {           // do the default
           return _old.apply(this,arguments);
        }
    };

我们还可以访问_old方法,因为它的范围存在于当前上下文中。然后,我们可以在新方法中使用它。

我们在_old的帮助下调用了apply方法,因为我们希望也有相同的this上下文。

通过这种方法,我们可以通过保留其原始功能轻松覆盖jQuery方法。