var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,rmultiDash= /([A-Z])/g;function internalData( elem, name, data, pvt /*Internal Use Only*/){//如果elem元素不能附加值,退出if ( !jQuery.acceptData( elem ) ) {return;}//## form core.js//Unique for each copy of jQuery on the page//Non-digits removed to match rinlinejQuery//expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),//每个Jquery都有单独的一个expandovarret, thisCache,internalKey=jQuery.expando,//We have to handle DOM nodes and JS objects differently because IE6-7//can't GC object references properly across the DOM-JS boundary//由于IE6,7不能自动回收再DOM上的引用,所以要对DOM和JS对象区别对待isNode =elem.nodeType,//Only DOM nodes need the global jQuery cache; JS object data is//attached directly to the object so GC can occur automatically//只有DOM需要全局的缓存变量,对象就直接插入值了cache = isNode ?jQuery.cache : elem,//Only defining an ID for JS objects if its cache already exists allows//the code to shortcut on the same path as a DOM node with no cacheid = isNode ? elem[ internalKey ] : elem[ internalKey ] &&internalKey;//什么时候会出现id为undefined的时候?//internalData(document.createElement('div'),'namea',...)//internalData({});//Avoid doing any more work than we need to when trying to get data on an//object that has no data at allif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string") {return;}//如果有name而没有data,说明这是一个读取的动作//但是没有得到id,获取cache[id]中啥都没有,在获取用户数据的时候cache[id].data啥都木有,就返回空if ( !id ) {//Only DOM nodes need a new unique ID for each element since their data//ends up in the global cache//如果是DOM元素,则取得一个唯一的ID值if( isNode ) {id= elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++; }else{id= internalKey; //这是jQuery.expando
}}if ( !cache[ id ] ) {//Avoid exposing jQuery metadata on plain JS objects when the object//is serialized using JSON.stringify//避免只用JSON.stringify(cache[id]) 所带来的循环引用cache[ id ] = isNode ?{} : { toJSON: jQuery.noop };}//An object can be passed to jQuery.data instead of a key/value pair; this gets//shallow copied over onto the existing cache//也可以穿一个jQuery.data,浅拷贝过来//jQuery.data({},{name:'hhstuhacker',age:31})//cache[id] = {data:{name:'hhstuhacker',age:31}};//cache[ id ]存入的是jQuery的内部数据//cache[ id ].data 存入的是用户数据//若果pvt为真,就拷贝到cache[ id ]里//若果pvt为false,就拷贝到cache[ id ].data 里if ( typeof name === "object" || typeof name === "function") {if( pvt ) {cache[ id ]= jQuery.extend( cache[ id ], name ); //直接拷贝,内部使用} else{cache[ id ].data= jQuery.extend( cache[ id ].data, name ); //直接拷贝data
}}thisCache=cache[ id ];//jQuery data() is stored in a separate object inside the object's internal data//cache in order to avoid key collisions between internal data and user-defined//data.//jQuery.cache = {jQuery.expando: {data:{}}};//这里是为了防止内部数据跟用户定义的数据项混淆,内部数据定义在jQ.cache里,用户定义数据在jQ.cache.[id] 里if ( !pvt ) {if ( !thisCache.data ) {thisCache.data={};}thisCache=thisCache.data;}//分情况了,如果传入了键值对,就设置之//将camelCase驼峰if ( data !==undefined ) {thisCache[ jQuery.camelCase( name ) ]=data;}//Check for both converted-to-camel and non-converted data property names//If a data property was specified//不管是否读取还是设置缓存,都会返回数据//先尝试直接获取,如果获取不成功,就尝试驼峰式获取//如果连name都没有指定,就获取整个thisCache对象if ( typeof name === "string") {//First Try to find as-is property dataret =thisCache[ name ];//Test for null|undefined property dataif ( ret == null) {//Try to find the camelCased propertyret =thisCache[ jQuery.camelCase( name ) ];}}else{ret=thisCache;}returnret;
}functioninternalRemoveData( elem, name, pvt ) {if ( !jQuery.acceptData( elem ) ) { //如果elem元素不能附加值,退出return; }varthisCache, i,isNode=elem.nodeType,//See jQuery.data for more informationcache = isNode ?jQuery.cache : elem,id= isNode ?elem[ jQuery.expando ] : jQuery.expando;//If there is already no cache entry for this object, there is no//purpose in continuing//如果没有得到cache[ id ] 那就不进行了if ( !cache[ id ] ) {return;}if( name ) {thisCache= pvt ?cache[ id ] : cache[ id ].data;if( thisCache ) {//Support array or space separated string names for data keys//$.removeData(element,['title','age','createTime']);//$.removeData(element,'title age createTime');if ( !jQuery.isArray( name ) ) {//try the string as a key before any manipulationif ( name inthisCache ) {name=[ name ];}else{//split the camel cased version by spaces unless a key with the spaces exists//检测是否驼峰式在其中,如果不在,将其splitname =jQuery.camelCase( name );if ( name inthisCache ) {name=[ name ];}else{name= name.split(" ");}}}else{//If "name" is an array of keys...//When data is initially created, via ("key", "val") signature,//keys will be converted to camelCase.//Since there is no way to tell _how_ a key was added, remove//both plain key and camelCase key. #12786//This will only penalize the array argument path.name =name.concat( jQuery.map( name, jQuery.camelCase ) );//将不驼峰和驼峰的全部删除
}//删除之i =name.length;while ( i--) {deletethisCache[ name[i] ];}//If there is no data left in the cache, we want to continue//and let the cache object itself get destroyed//如果说删除过后,cache[id]或者cache[id].data 都是空了,那么咱们需要清理下一步吧?if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {return;}}}//See jQuery.data for more information//如果是用户使用的话,清空cache[id].data//如果cache [ id ] 不是空的话,结束该函数//如果cahce [ id ] 是空的话,还是下一步的清理行动啊if ( !pvt ) {deletecache[ id ].data;//Don't destroy the parent cache unless the internal data object//had been the only thing left in itif ( !isEmptyDataObject( cache[ id ] ) ) {return;}}//window.window === window;//isWindow: function (o) {return o.window === window;}//cache != cache.window 表示不是window//Destroy the cache//如果是个DOM节点,那么cleanDataif( isNode ) {jQuery.cleanData( [ elem ],true);//ses: http://www.cnblogs.com/enein/archive/2012/08/23/2651312.html//Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)//经测试,在IE6,7,8下面,var div = document.createElement('div') delete div.test;//是报错的 而 jQuery.support.deleteExpando 正是这种检测} else if ( jQuery.support.deleteExpando || cache !=cache.window ) {deletecache[ id ];//When all else fails, null} else{cache[ id ]= null;}
}jQuery.extend({cache: {},//The following elements throw uncatchable exceptions if you//attempt to add expando properties to them.//这几个元素不能有附加值
noData: {"applet": true,"embed": true,//Ban all objects except for Flash (which handle expandos)"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function( elem ) {elem= elem.nodeType ?jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];return !!elem && !isEmptyDataObject( elem );},data:function( elem, name, data ) {returninternalData( elem, name, data );},removeData:function( elem, name ) {returninternalRemoveData( elem, name );},//For internal use only.//内部适用,这里设置pvt为true,返回内部数据,定位到cache[id]这一层_data: function( elem, name, data ) {return internalData( elem, name, data, true);},//内部适用,这里设置pvt为true,返回内部数据,定位到cache[id]这一层_removeData: function( elem, name ) {return internalRemoveData( elem, name, true);},//A method for determining if a DOM node can handle the data expandoacceptData: function( elem ) {//Do not set data on non-element because it will not be cleared (#8335).//如果是个dom节点,并且不是element也不是document,那就表示不能被附加数据//see:http://www.cnblogs.com/hhstuhacker/p/NodeType.htmlif ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9) {return false;}var noData = elem.nodeName &&jQuery.noData[ elem.nodeName.toLowerCase() ];//nodes accept data unless otherwise specified; rejection can be conditional//如果是embed或者applet,或者是flash元素,就返回false//about falsh:: http://www.w3help.org/zh-cn/causes/HO8001return !noData || noData !== true && elem.getAttribute("classid") ===noData;}
});jQuery.fn.extend({data:function( key, value ) {varattrs, name,data= null,i= 0,elem= this[0];//Special expections of .data basically thwart jQuery.access,//so implement the relevant behavior ourselves//Gets all values//如果key为undefined,那就表示要取得所有的dataif ( key ===undefined ) {if ( this.length ) { data= jQuery.data( elem ); //默认取第一个//看看cache内部是否已经解析过该DOM了,parsedAttrs//如果没有,得到属性列表if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs") ) {attrs=elem.attributes;for ( ; i < attrs.length; i++) {name=attrs[i].name;if ( name.indexOf("data-") === 0) {name= jQuery.camelCase( name.slice(5) );//这里的data[ name ]为空值
dataAttr( elem, name, data[ name ] );}}//标记已经解析过了jQuery._data( elem, "parsedAttrs", true);}}returndata;}//Sets multiple values//如果是个对象,递归调用之if ( typeof key === "object") {return this.each(function() {jQuery.data(this, key );});}return arguments.length > 1 ?//Sets one valuethis.each(function() {jQuery.data(this, key, value );}) ://$('.color-box').data('someone','new');//Gets one value//Try to fetch any internally stored data firstelem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;//$('#box').data('dataFirst');//<div data-data-first="something....."></div>
},removeData:function( key ) {return this.each(function() {jQuery.removeData(this, key );});}
});functiondataAttr( elem, key, data ) {//If nothing was found internally, try to fetch any//data from the HTML5 data-* attribute//这个函数,主要是处理HTML5的问题if ( data === undefined && elem.nodeType === 1) {//驼峰反转var name = "data-" + key.replace( rmultiDash, "-$1").toLowerCase();data=elem.getAttribute( name );//rbrace 对象或者数组正则if ( typeof data === "string") {try{data= data === "true" ? true:data=== "false" ? false:data=== "null" ? null://Only convert to a number if it doesn't change the string+data + "" === data ? +data :rbrace.test( data )?jQuery.parseJSON( data ) :data;}catch( e ) {}//Make sure we set the data so it isn't changed later
jQuery.data( elem, key, data );//设置进去
}else{data=undefined;}}returndata;
}//checks a cache object for emptiness
functionisEmptyDataObject( obj ) {varname;for ( name inobj ) {//if the public data object is empty, the private is still empty//如果cache.data 为空,跳过本次循环,不判断了//如果不跳过啊,就走到下面了吧,name !== data 杠杠的if ( name === "data" &&jQuery.isEmptyObject( obj[name] ) ) {continue;}//toJSON是内置的,如果看到其他name,就不为空if ( name !== "toJSON") {return false;}}return true;
}

jQuery的版本为1.9.2

转载于:https://www.cnblogs.com/hhstuhacker/p/inside_jquery_source_data.html

读jQuery源码 jQuery.data相关推荐

  1. jQuery源码-jQuery.fn.each jQuery.each

    先上例子,下面代码的作用是:对每个选中的div元素,都给它们添加一个red类 $('div').each(function(index, elem){$(this).addClass('red'); ...

  2. jquery源码--jquery对象

    (function( window, undefined ) {// 构造 jQuery 对象 22 var jQuery = (function() { 25 var jQuery = functi ...

  3. JQuery源码-------JQuery中数值型变量的判断isNumeric

    判断一个数值型变量的方法,在jquery中非常简单,只有一行代码. isNumeric: function( obj ) {// parseFloat NaNs numeric-cast false ...

  4. 深入学习jquery源码之queue()与dequeue()

    深入学习jquery源码之queue()与dequeue() queue(element,[queueName]) 概述 显示或操作在匹配元素上执行的函数队列 参数 element,[queueNam ...

  5. 深入学习jquery源码之jQuery的选择器引擎Sizzle(一)

    深入学习jquery源码之jQuery的选择器引擎Sizzle Sizzle是一个纯javascript CSS选择器引擎.jquery1.3开始使用sizzle,Sizzle一反传统采取了相反的Ri ...

  6. jQuery源码分析(二)——Sizzle

    在这一章中我们将重点分析jquery的选择器引擎.jquery在3.4版本后,将选择器引擎抽取出来单独放到了Sizzle.js 文件中,本文将基于这个版本来进行分析. 创建缓存 // line 40 ...

  7. jQuery源码学习之Callbacks

    jQuery源码学习之Callbacks jQuery的ajax.deferred通过回调实现异步,其实现核心是Callbacks. 使用方法 使用首先要先新建一个实例对象.创建时可以传入参数flag ...

  8. jquery 源码分析初步

    jquery 所有版本下载和引用地址 http://www.jq22.com/jquery-info122 一 jquery源码要点 jQuery框架的核心就是从HTML文档中匹配元素并对其执行操作 ...

  9. [转] jQuery源码分析-如何做jQuery源码分析

    jQuery源码分析系列(持续更新) jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我基本按照这样的顺序去学习. 当我读到难度的书或者源码时,会和<如何阅读一本书> ...

最新文章

  1. Properties持久的属性集
  2. java对接ldap_如何使用Java操作LDAP之LDAP连接(一)
  3. Android CardView的基本使用
  4. ReentrantLock实现原理
  5. 度量 数据突变_使用K-Means和PCA进行基因组序列分析 COVID-19接下来如何突变?
  6. 软件测试高频面试题真实分享/网上银行转账是怎么测的,设计一下测试用例。
  7. 什么是人工智能?(科普)
  8. 如何批量打印jpg图片
  9. 巃嵸鸿蒙构瑰材兮,明堂赋原文、翻译及赏析_李白古诗_风萧学古网
  10. 基于深度学习的推荐系统综述 (arxiv 1707.07435) 译文 3.1 ~ 3.3
  11. win7怎么查看计算机主板,win7系统电脑查看主板型号的四种方法介绍
  12. .htaccess重写、安全防护、文件访问权限
  13. 2021-2027全球及中国红外探测器芯片行业研究及十四五规划分析报告
  14. 苹果开发者账号(公司级)和邓白氏编码(D-U-N-S)申请记录(2015.06)
  15. C++:using : using的四大用法总结
  16. Python爬虫-Selenium(1)
  17. 基于android的电子词典设计_基于Android平台下的电子词典的设计与实现
  18. 电脑连接蓝牙耳机声音总是断断续续:
  19. 数据库PostrageSQL-WAL配置
  20. 直播提醒 | 零基础深度学习极速入门课程重磅开营

热门文章

  1. easyui的tree节点的获取和选中
  2. 【解决方案】钉钉直播课堂挂机被点到名字怎么办
  3. Spring→事务、隔离级别、事务传播行为、编程式事务控制、XML配置声明式事务(原始方式)、XML配置声明式事务(基于tx/aop)、@注解配置声明式事务、优势总结
  4. C++ 实现一个简单内存池
  5. 2014C++A:蚂蚁感冒(数组+判断)
  6. bzoj 1605: [Usaco2008 Open]Crisis on the Farm 牧场危机(DP)
  7. bzoj 1667: [Usaco2006 Oct]Cows on Skates滑旱冰的奶牛(BFS)
  8. bzoj 1293: [SCOI2009]生日礼物
  9. C++ STL inner_product函数的使用方法
  10. java图片亮度调整