jQuery技术

jQuery 源码系列(八)data 缓存机制(2)

字号+ 作者:H5之家 来源:H5之家 2017-03-05 11:03 我要评论( )

var dataPriv = new Data(); //以后会讲到var dataUser = new Data();jQuery.extend( {hasData: function( elem ) {return dataUser.hasData( elem ) || dataPriv.hasData( elem );},data: function( elem, name, d

var dataPriv = new Data(); //以后会讲到 var dataUser = new Data(); jQuery.extend( { hasData: function( elem ) { return dataUser.hasData( elem ) || dataPriv.hasData( elem ); }, data: function( elem, name, data ) { return dataUser.access( elem, name, data ); }, removeData: function( elem, name ) { dataUser.remove( elem, name ); }, // TODO: Now that all calls to _data and _removeData have been replaced // with direct calls to dataPriv methods, these can be deprecated. _data: function( elem, name, data ) { return dataPriv.access( elem, name, data ); }, _removeData: function( elem, name ) { dataPriv.remove( elem, name ); } } );

源码里面有 dataPriv 和 dataUser,作者做了一个 TODO 标记,

接着是 jQuery.fn.data() :

jQuery.fn.extend( { data: function( key, value ) { var i, name, data, // 将第一个 dom 赋给 elem elem = this[ 0 ], attrs = elem && elem.attributes; // key 为 underfined,表示参数空,获取全部 if ( key === undefined ) { if ( this.length ) { data = dataUser.get( elem ); if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { i = attrs.length; while ( i-- ) { // 这里面从 dom 的 attribute 中搜索 data- 开通的属性 if ( attrs[ i ] ) { name = attrs[ i ].name; if ( name.indexOf( "data-" ) === 0 ) { name = jQuery.camelCase( name.slice( 5 ) ); dataAttr( elem, name, data[ name ] ); } } } dataPriv.set( elem, "hasDataAttrs", true ); } } return data; } // object 类型 if ( typeof key === "object" ) { return this.each( function() { dataUser.set( this, key ); } ); } // key value 的情况,利用 access 函数 return access( this, function( value ) { var data; // The calling jQuery object (element matches) is not empty // (and therefore has an element appears at this[ 0 ]) and the // `value` parameter was not undefined. An empty jQuery object // will result in `undefined` for elem = this[ 0 ] which will // throw an exception if an attempt to read a data cache is made. if ( elem && value === undefined ) { // Attempt to get data from the cache // The key will always be camelCased in Data data = dataUser.get( elem, key ); if ( data !== undefined ) { return data; } // Attempt to "discover" the data in // html5 custom data-* attrs data = dataAttr( elem, key ); if ( data !== undefined ) { return data; } // We tried really hard, but the data doesn't exist. return; } // Set the data... this.each( function() { // We always store the camelCased key dataUser.set( this, key, value ); } ); }, null, value, arguments.length > 1, null, true ); }, removeData: function( key ) { return this.each( function() { dataUser.remove( this, key ); } ); } } );

data 函数略有不同,但思路也很清晰。

有几个要提一下的函数

其中,有几个函数,也来介绍一下, acceptData :

var acceptData = function( owner ) { // Accepts only: // - Node // - Node.ELEMENT_NODE // - Node.DOCUMENT_NODE // - Object // - Any return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); };

acceptData 是判断 owner 的类型,具体关于 nodeType,去看看 这里 吧。

jQuery.camelCase :

jQuery.camelCase = function (string) { return string.replace(/^-ms-/, "ms-").replace(/-([a-z])/g, function (all, letter) { return letter.toUpperCase(); }); }

这个函数就是做了一些特殊字符串的 replace,具体有啥用,我也不是很清楚。

isEmptyObject 是判断一个 Object 是否为空的函数,挺有意思的,可以借鉴:

jQuery.isEmptyObject = function (obj) { var name; for (name in obj) { return false; } return true; }

dataAttr 是一个从 DOM 中搜索以 data- 开头属性的函数:

function dataAttr( elem, key, data ) { var name; // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { name = "data-" + key.replace( /[A-Z]/g, "-$&" ).toLowerCase(); // 利用 dom 自身的 get 操作 data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { // 先看有没有 data = getData( data ); } catch ( e ) {} // Make sure we set the data so it isn't changed later dataUser.set( elem, key, data ); } else { data = undefined; } } return data; } 总结

jQuery 的 data 缓存从源码来看的话,真的不是很难,而且不难发现,jQuery 缓存的实质, 其实就是在内部先弄一个 Object,然后和缓存体(DOM)建立一对一的联系,所有增删改查的操作,都是围绕着 jQuery 内部来的,不直接对 DOM 操作,这样就可以避免内存泄漏 。而且从源码来看,jQuery 的缓存机制自带清内存操作,更是锦上添花呀。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • jQuery常用API jQuery

    jQuery常用API jQuery

    2017-03-01 15:00

  • What’s New In jQuery 3 : 17 Added Features amp; How To Use T

    What’s New In jQuery 3 : 17 Added Features amp; How To Use T

    2017-02-11 18:01

  • jquery源码学习笔记三:jQuery工厂剖析

    jquery源码学习笔记三:jQuery工厂剖析

    2017-01-18 17:03

  • jQuery实现字符串全部替换的方法

    jQuery实现字符串全部替换的方法

    2016-12-15 13:07

网友点评