zoukankan      html  css  js  c++  java
  • jQuery中$.proxy()的原理和使用

    jQuery.proxy(),接受一个函数,然后返回一个新函数,并且这个新函数始终保持了特定的上下文(context )语境

    • jQuery.proxy( function, context )

      function:将要改变上下文语境的函数。

      context:函数的上下文语境(`this`)会被设置成这个 object 对象。

    • jQuery.proxy( context, name )

      context:函数的上下文语境会被设置成这个 object 对象。

      name:将要改变上下文语境的函数名(这个函数必须是前一个参数 ‘context’ 对象的属性)

    这个方法通常在向一个元素上附加事件处理函数时,上下文语境实际是指向另一个对象的情况下使用。

    另外,jQuery 能够确保即使你绑定的函数是经过 jQuery.proxy() 处理过的函数,你依然可以用原先的函数来正确地取消绑定。

    看一下官方的例子:

    var obj = {
    name: "John",
    test: function() {
    alert( this.name );
    $("#test").unbind("click", obj.test);
    }
    };
    
    $("#test").click( jQuery.proxy( obj, "test" ) );
    
    // 以下代码跟上面那句是等价的:
    // $("#test").click( jQuery.proxy( obj.test, obj ) );
    
    // 可以与单独执行下面这句做个比较。
    // $("#test").click( obj.test );

    可以看一下jQuery中的实现(1.6之前的版本):

    /* jQuery 源码之 proxy:
     使用 apply 形式, 执行回调函数.
    */
    jQuery.proxy = function( fn, proxy, thisObject ) {
        if ( arguments.length === 2 ) {
            // jQuery.proxy(context, name);
            if ( typeof proxy === "string" ) {
                thisObject = fn;
                fn = thisObject[ proxy ];
                proxy = undefined;
    
                /* 转化结果:
                    thisObject -> context
                    fn -> name
                    proxy -> undefined
                 */
            }
            // jQuery.proxy(name, context);
            else if ( proxy && !jQuery.isFunction( proxy ) ) {
                thisObject = proxy;
                proxy = undefined;
            }
        }
        if ( !proxy && fn ) {
            /* 使用 proxy 保证 函数执行时, context 为指定值 */
            proxy = function() {
                return fn.apply( thisObject || this, arguments );
            };
        }
        // Set the guid of unique handler to the same of original handler, so it can be removed
        if ( fn ) {
            proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
        }
        // So proxy can be declared as an argument
        return proxy;
    }

    其实就是平常使用的的call和apply,大部分的时候作为回调使用。

    stackoverflow上有个问题,其中的例子比较典型,供参考:

    比如有如下代码:

    $('#myElement').click(function() {
    
            // In this function, "this" is our DOM element.
    
        $(this).addClass('aNewClass');
    
    });

    这里的this就是我们的DOM元素。如果我们要在增加class样式之前需要等待一段时间,可能会将代码写成下面这样(注意:有问题的代码):

    $('#myElement').click(function() {
    
        setTimeout(function() {
    
              // Problem! In this function "this" is not our element!
    
            $(this).addClass('aNewClass');
    
        }, 1000);
    
    });

    这里的this就不是我们期望的那个DOM元素了。解决方法就是使用jQuery的$.proxy()了,代码如下:

    $('#myElement').click(function() {
    
       // ------------------v--------give $.proxy our function,
    
        setTimeout($.proxy(function() {
    
            $(this).addClass('aNewClass');  // Now "this" is again our element
    
        }, this), 1000);
    
       // ---^--------------and tell it that we want our DOM element to be the
    
       //                      value of "this" in the function
    
    });

    我们可以这样来理解上面的代码:

    function() {
    
        // v--------func is the function we gave to $.proxy
    
        func.apply( ctx );
    
        // ----------^------ ctx is the value we wanted for "this" (our DOM element)
    
    }

    这就体现出来jQuery中$.proxy()的强大功效了。

    注意:在jQuery 1.6及之后的版本中,除了上面提到的两种用法之外,proxy还增加了其他两种用法:

    jQuery.proxy( function, context [, additionalArguments ] )
    jQuery.proxy( context, name [, additionalArguments ] )

    具体使用可以参考jQuery手册。

  • 相关阅读:
    Golang初学者的资源整理
    Mesos和kubernetes
    Go by Example
    dbus 和 policykit 实例篇(python) ()转
    CentOS7卸载KDE桌面(转)
    Please read “Security” section of the manual to find out how to run mysqld as root!错误解决(转)
    yum使用总结(转)
    Linux rpm 命令参数使用详解[介绍和应用](转)
    nginx+lua+redis高并发应用建设
    python网络爬虫进入(一)——简单的博客爬行动物
  • 原文地址:https://www.cnblogs.com/huntaheart/p/3854073.html
Copyright © 2011-2022 走看看