首页 > 代码库 > [原创]jQuery的this和$(this)

[原创]jQuery的this和$(this)

网上有很多关于jQuery的this和$(this)的介绍,大多数只是理清了this和$(this)的指向,其实它是有应用场所的,不能一概而论在jQuery调用成员函数时,this就是指向dom对象。

 

$(this)指向jQuery对象是无可厚非的,但this就是指向dom对象,这个是因为jQuery做了特殊的处理。 

 

在创建dom的jQuery对象时,jQuery不仅仅为dom创建一个jQuery对象,而且还将dom存储在所创建对象的数组中。

 

  elem = document.getElementById(match[2]);
  if (elem && elem.parentNode) {
    this.length = 1;
    this[0] = elem;
  }

  this.context = document;
  this.selector = selector;
  return this;

this[0] = elem这条语句就是实现对象数组。所以javascript是很有意思的语言,使用this访问时,可以访问它所指向的对象的成员函数,而其实this又是一个对象数组。其存放的是dom对象。

 

先看看 $("p").each() -- 循环

each: function( callback, args ) {
        return jQuery.each( this, callback, args );
    }

 看了each函数的调用大家应该明白,jQuery.each( this, callback, args );调用的是对象数组,而对象的数组存储的是dom对象,因此在callback函数中的this自然是dom对象了

 

 

再看看$("p").hide() -- 成员函数

hide: function() {
        return showHide( this );
    },
 function showHide( elements, show ) {var elem, display,
        values = [],
        index = 0,
        length = elements.length;

    for ( ; index < length; index++ ) {
        elem = elements[ index ];
        if ( !elem.style ) {
            continue;
        }
        values[ index ] = jQuery._data( elem, "olddisplay" );
        if ( show ) {
            // Reset the inline display of this element to learn if it is
            // being hidden by cascaded rules or not
            if ( !values[ index ] && elem.style.display === "none" ) {
                elem.style.display = "";
            }

            // Set elements which have been overridden with display: none
            // in a stylesheet to whatever the default browser style is
            // for such an element
            if ( elem.style.display === "" && isHidden( elem ) ) {
                values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
            }
        } else {
            display = curCSS( elem, "display" );

            if ( !values[ index ] && display !== "none" ) {
                jQuery._data( elem, "olddisplay", display );
            }
        }
    }

    // Set the display of most of the elements in a second loop
    // to avoid the constant reflow
    for ( index = 0; index < length; index++ ) {
        elem = elements[ index ];
        if ( !elem.style ) {
            continue;
        }
        if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
            elem.style.display = show ? values[ index ] || "" : "none";
        }
    }

    return elements;
}

从上面的代码可以看出hide行数其实调用的是showHide,而传入的第一个参数this,并不是dom对象,而是jQuery对象数组,因此showHide函数通过循环此对象数组获取每一个dom对象。

 

最后看看$("p").bind() -- 事件

bind: function( types, data, fn ) {
        return this.on( types, null, data, fn );
    },

on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
        // 此部分代码省略
        return this.each( function() {
            jQuery.event.add( this, types, fn, data, selector );
        });
    },

bind函数调用的是 on函数,而on函数又是通过 each函数实现了jQuery.event.add。因此 jQuery.event.add( this中的this也就是dom对象了。所以事件中的this也就是dom对象了。

<iframe id="google_ads_frame2" vspace="0" height="250" marginHeight="0" src="http://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-3447371224873639&output=html&h=250&slotname=8660799060&adk=1970350646&w=300&lmt=1401191266&flash=0&url=http%3A%2F%2Fwww.cnblogs.com%2Franzige%2Fp%2F3753536.html&dt=1401191268410&shv=r20140520&cbv=r20140417&saldr=sb&correlator=1401191268155&frm=20&ga_vid=1304086684.1400769066&ga_sid=1401189498&ga_hid=1535780574&ga_fc=1&u_tz=480&u_his=17&u_java=1&u_h=768&u_w=1364&u_ah=768&u_aw=1364&u_cd=16&u_nplug=0&u_nmime=0&dff=tahoma&dfs=12&adx=0&ady=2419&biw=314&bih=74&eid=317150304%2C42631032&oid=3&rx=0&eae=0&docm=9&vis=0&fu=0&ifi=2&xpc=aR7sSlYX8E&p=http%3A//www.cnblogs.com&dtd=41" frameBorder="0" width="300" allowTransparency="true" name="google_ads_frame2" marginWidth="0" scrolling="no" hspace="0"></iframe><iframe id="google_ads_frame3" vspace="0" height="250" marginHeight="0" src="http://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-3447371224873639&output=html&h=250&slotname=8660799060&adk=1970350646&w=300&lmt=1401191266&flash=0&url=http%3A%2F%2Fwww.cnblogs.com%2Franzige%2Fp%2F3753536.html&dt=1401191268458&shv=r20140520&cbv=r20140417&saldr=sb&prev_slotnames=8660799060&correlator=1401191268155&frm=20&ga_vid=1304086684.1400769066&ga_sid=1401189498&ga_hid=1535780574&ga_fc=1&u_tz=480&u_his=17&u_java=1&u_h=768&u_w=1364&u_ah=768&u_aw=1364&u_cd=16&u_nplug=0&u_nmime=0&dff=tahoma&dfs=12&adx=304&ady=2669&biw=314&bih=74&eid=317150304%2C42631032&oid=3&rx=0&eae=0&docm=9&vis=0&fu=0&ifi=3&xpc=h3MrIJUnGi&p=http%3A//www.cnblogs.com&dtd=40" frameBorder="0" width="300" allowTransparency="true" name="google_ads_frame3" marginWidth="0" scrolling="no" hspace="0"></iframe>