
下面分别解读
1、Data.uid
这是一个从 1 开始用来自增的数字。
2、expando
由 jQuery.expando 和 uid 组合而成,它用来作为元素(如DOM元素)的key,是唯一的。jQuery.expando 的生成如下
jQuery.expando = "jQuery" + ( version + Math.random() ).replace( /D/g, "" )即 "jQuery" + (版本号 + 随机数),然后把非数字的都去掉,比如
"jQuery" + ".." + . == "jQuery..."去掉非数字变为
jQuery30009423638425146147"jQuery 3.0 内部变量 dataPriv 和 dataUser 生成 expando 如下
jQuery 300 024727210109188635 1jQuery 300 024727210109188635 2第三部分是随机数,每次刷新都会变,其它部分的不变。
var acceptData = function( owner ) {// Accepts only:// - Node//- Node.ELEMENT_NODE//- Node.DOCUMENT_NODE// - Object//- Any/* jshint -W018 */return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );};acceptData 在 3.0 中一共有 3 处使用,分别为// If it is a node unlikely to be stringify-ed or looped over// use plain assignmentif ( owner.nodeType ) {owner[ this.expando ] = value;// Otherwise secure it in a non-enumerable property// configurable must be true to allow the property to be// deleted when data is removed} else {Object.defineProperty( owner, this.expando, {value: value,configurable: true} );}转换成如下代码elem["jQuery3000247272101091886351"] = dataObj;var person = {name: "John", age: 30};Object.defineProperty( person, "jQuery3000247272101091886351", {value: dataObj,configurable: true} );cache 方法就是这样,传入 owner,只有第一次会 set ,返回 value (一个空对象),之后取到 value 后直接返回。cache: function( owner ) {// Check if the owner object already has a cachevar value = owner[ this.expando ];// If not, create oneif ( !value ) {value = {};// We can accept data for non-element nodes in modern browsers,// but we should not, see #8335.// Always return an empty object.if ( acceptData( owner ) ) {// If it is a node unlikely to be stringify-ed or looped over// use plain assignmentif ( owner.nodeType ) {owner[ this.expando ] = value;// Otherwise secure it in a non-enumerable property// configurable must be true to allow the property to be// deleted when data is removed} else {Object.defineProperty( owner, this.expando, {value: value,configurable: true} );}}}return value;},4、setset: function( owner, data, value ) {var prop,cache = this.cache( owner );// Handle: [ owner, key, value ] args// Always use camelCase key (gh-2257)if ( typeof data === "string" ) {cache[ jQuery.camelCase( data ) ] = value;// Handle: [ owner, { properties } ] args} else {// Copy the properties one-by-one to the cache objectfor ( prop in data ) {cache[ jQuery.camelCase( prop ) ] = data[ prop ];}}return cache;},5、getget: function( owner, key ) {return key === undefined ?this.cache( owner ) :// Always use camelCase key (gh-2257)owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];},6、accessaccess: function( owner, key, value ) {// In cases where either:////1. No key was specified//2. A string key was specified, but no value provided//// Take the "read" path and allow the get method to determine// which value to return, respectively either:////1. The entire cache object//2. The data stored at the key//if ( key === undefined ||( ( key && typeof key === "string" ) && value === undefined ) ) {return this.get( owner, key );}// When the key is not a string, or both a key and value// are specified, set or extend (existing objects) with either:////1. An object of properties//2. A key and value//this.set( owner, key, value );// Since the "set" path can have two possible entry points// return the expected data based on which path was taken[*]return value !== undefined ? value : key;},7、removeremove: function( owner, key ) {var i,cache = owner[ this.expando ];if ( cache === undefined ) {return;}if ( key !== undefined ) {// Support array or space separated string of keysif ( jQuery.isArray( key ) ) {// If key is an array of keys...// We always set camelCase keys, so remove that.key = key.map( jQuery.camelCase );} else {key = jQuery.camelCase( key );// If a key with the spaces exists, use it.// Otherwise, create an array by matching non-whitespacekey = key in cache ?[ key ] :( key.match( rnotwhite ) || [] );}i = key.length;while ( i-- ) {delete cache[ key[ i ] ];}}// Remove the expando if there"s no more dataif ( key === undefined || jQuery.isEmptyObject( cache ) ) {// Support: Chrome <=35 - 45// Webkit & Blink performance suffers when deleting properties// from DOM nodes, so set to undefined instead// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)if ( owner.nodeType ) {owner[ this.expando ] = undefined;} else {delete owner[ this.expando ];}}}, 8、hasDatahasData: function( owner ) {var cache = owner[ this.expando ];return cache !== undefined && !jQuery.isEmptyObject( cache );}二、Data在jQuery内部的使用
完整版点击展开可查看
dataPriv公共$.hasData$.cleanDatacloneCopyEvent队列$().queue$()._queueHooks$().promise动画$().animate$().stop$().finishshowHide事件$.event.add$.event.remove$.event.dispatch$.event.trigger其它setGlobalEvaldomManipdefaultPrefilter$().toggleClassdataUser公共$.hasData$.cleanDatacloneCopyEvent数据缓存$.data$.removeData$().data$().removeData其它dataAttr以上可以看到,除了“公共”,DataPriv 用在了 jQuery 的 队列、动画、事件等模块;dataUser 用在了数据缓存及dataAttr模块。
hasData: function( elem ) {return dataUser.hasData( elem ) || dataPriv.hasData( elem );},$.cleanData(elems)var cloneNode = $.clone(elem);把 elem 克隆给 cloneNode,此时 elem 上添加的事件 cloneNode 上也会有。

3. 重构
1.x 以 $._data 为中心,以它来辅助实现其它 API, (2/3).x 以 dataPriv/dataUser 为中心来实现。(2/3).x 将代码重构后提取出了 Data 类,更加清晰。
以上所述是小编给大家介绍的jQuery 3.0中的Data的全部叙述,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!