jQuery数据缓存方案详解:$.data()的使用
我们经常使用隐藏控件或者是js全局变量来临时存储数据,全局变量容易导致命名污染,隐藏控件导致经常读写dom浪费性能。jQuery提供了自己的数据缓存方案,能够达到和隐藏控件、全局变量相同的效果,但是jQuery实现方式更优雅。为了更好地使用jQuery数据缓存方案,我们需要掌握$.data()、$.cache、$.expando、$.hasData()、$.removeData()。
$.hasData()用来判断某个对象是否有附加的属性,可以给任何JavaScript对象和HTMLElement对象附加属性。$.data()用来读取或者修改属性值。$.removeData()用来删除已经添加的属性,这是为了释放内存,避免过多无用属性浪费内存。
- var myObj = {};
- // hasData用来判断HTMLElement或JS对象是否具有数据
- console.log(jQuery.hasData($("#a")));// false
- // data()添加属性
- $.data(myObj, 'name', 'aty');
- console.log(jQuery.hasData(myObj));// true
- // data()读取属性
- console.log($.data(myObj, 'name'));//aty
- // removeData删除属性
- $.removeData(myObj, 'name');
- console.log($.data(myObj, 'name'));//undefined
- // 如果所有属性都被删除,那么hasData返回false
- console.log(jQuery.hasData(myObj));// false
给HTMLElement对象添加属性,使用方式跟为普通js对象添加属性一模一样。
- <div id="content"></div>
- <script>
- var el = document.getElementById('content');
- $.data(el, 'name', 'aty');
- console.log($.data(el, 'name')); // aty
- </script>
可以看到使用jQuery数据缓存的API是很容易的,现在我们要大致看下jQuery是如何实现缓存方案。为普通JS对象提供缓存时,jquery直接将数据保存在原始的JS对象上。此时会偷偷的给JS对象添加个属性(类似于jQuery16101803968874529044),属性值也是一个对象。
- var myObj = {};
- $.data(myObj, 'name', 'aty');
- console.log(myObj);
- console.log($.expando);
我们可以看到myObj结构发生了变化:jquery给普通对象偷偷添加的属性名称其实就是$.expando。
jQuery.expando是一个字符串,使用Math.random生成,去掉了非数字字符。它作为HTMLElement或JS对象的属性名。页面引入jQuery框架的时候,会随机生成一个字符串。
- expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
现在我们知道了jQuery如何给普通对象添加属性,以及expando的含义,那么我们就可以通过下面的代码获取添加的属性。
- var hisObj = {};
- $.data(hisObj, 'name', 'him');
- console.log(hisObj[jQuery.expando].data.name);//him
为HTMLElement提供缓存时,却不会直接保存在HTMLElement上。而是保存在jQuery.cache这个全局对象上。此时先给HTMLElement添加属性(jQuery.expando),属性值为数字(1,2,3递增)。即只将一些数字保存在了HTMLElement上,不会直接将数据置入。这是因为IE老版本中可能会存在内存泄露危险。而HTMLElement如何与jQuery.cache建立联系呢? 还是id。刚刚提到属性值数字就是id。
- <div id="a"></div>
- <script>
- var dom = document.getElementById("a");
- $.data(dom, 'name', 'aty');
- console.log(dom[jQuery.expando]); // 1
- console.log(jQuery.cache); // {1 : {data:{name:'aty'}}}
- </script>
知道了jQuery如何为dom对象添加属性,我们就可以通过下面的代码获取属性。
- console.log(jQuery.cache[dom[jQuery.expando]].data.name);
现在我们看下DOM对象和jQuery封装后的对象有什么区别。
- // 给dom元素添加数据
- var dom = document.getElementById("a");
- $.data(dom, 'name', 'aty');
- console.log(jQuery.hasData(dom));//true
- console.log($.data(document.getElementById("a"), 'name'));//aty
- console.log($.data($("#a")[0], 'name'));//aty
- // 给jquery包装后的dom附加对象
- var $dom = $("#a");
- $.data($dom, 'age', '25');
- console.log(jQuery.hasData($dom));//true
- console.log($.data($dom, 'age'));//25
- console.log($.data($("#a"), 'age'));//undefined
这是因为本质区别在于:原始的DOM对象会被jQuery特殊对待,而jQuery包装后的对象与普通JS对象无异。通过jQuery选择器每次获取的对象并不是同一个对象。
- var $dom = $("#a");
- $.data($dom, 'age', '25');
- // dom对象支持多次获取,jQuery对象不支持
- console.log( document.getElementById("a") === document.getElementById("a"));///true
- console.log( document.getElementById("a") === $("#a")[0]);///true
- console.log($("#a") === $("#a"));//false
- // jQuery包装后的对象,与普通javascript对象无异
- console.log($dom[jQuery.expando].data.age);//25
最后再提一下,可以使用$.data获取某个对象上附加的所有属性。
- var $dom = $("#a");
- $.data($dom, 'age', '25');
- console.log($.data($dom));//Object {age: "25"}
参考文章:
读jQuery之六(缓存数据)
jQuery数据缓存方案详解:$.data()的使用的更多相关文章
- jquery源码解析:jQuery数据缓存机制详解2
上一课主要讲了jQuery中的缓存机制Data构造方法的源码解析,这一课主要讲jQuery是如何利用Data对象实现有关缓存机制的静态方法和实例方法的.我们接下来,来看这几个静态方法和实例方法的源码解 ...
- jquery源码解析:jQuery数据缓存机制详解1
jQuery中有三种添加数据的方法,$().attr(),$().prop(),$().data().但是前面两种是用来在元素上添加属性值的,只适合少量的数据,比如:title,class,name等 ...
- java——包装类数据缓存 ==号详解
Java对部分经常使用的数据采用缓存技术,即第一次使用该数据则创建该数据对象并对其进行缓存, 当再次使用等值对象时直接从缓存中获取,从而提高了程序执行性能.(只对常用数据进行缓存) Java中只是对部 ...
- Oracle DataGuard数据备份方案详解
Oracle DataGuard是一种数据库级别的HA方案,最主要功能是冗灾.数据保护.故障恢复等. 在生产数据库的"事务一致性"时,使用生产库的物理全备份(或物理COPY)创建备 ...
- HTML5数据存储方案data与jQuery数据存储方案$.data()的区别
我们先看下$.fn.data()的使用,这个和$.data()是不一样的,前者是和某个jquery对象相关,后者则是全局方法.主要有data()和removeData()这2个实例方法.通过下面的例子 ...
- jQuery数据缓存data(name, value)详解及实现
一. jQuery数据缓存的作用 jQuery数据缓存的作用在中文API中是这样描述的:“用于在一个元素上存取数据而避免了循环引用的风险”.如何理解这句话呢,看看我下面的举例,不知道合不合适,如果你有 ...
- jQuery源代码学习之六——jQuery数据缓存Data
一.jQuery数据缓存基本原理 jQuery数据缓存就两个全局Data对象,data_user以及data_priv; 这两个对象分别用于缓存用户自定义数据和内部数据: 以data_user为例,所 ...
- jQuery数据缓存$.data 的使用以及源码解析
一.实现原理: 对于DOM元素,通过分配一个唯一的关联id把DOM元素和该DOM元素的数据缓存对象关联起来,关联id被附加到以jQuery.expando的值命名的属性上,数据存储在全局缓存对象jQu ...
- 触碰jQuery:AJAX异步详解
触碰jQuery:AJAX异步详解 传送门:异步编程系列目录…… 示例源码:触碰jQuery:AJAX异步详解.rar AJAX 全称 Asynchronous JavaScript and XML( ...
随机推荐
- 编译安装PHP7并安装Redis扩展Swoole扩展
编译安装PHP7并安装Redis扩展Swoole扩展 在编译php7的机器上已经有编译安装过php5.3以上的版本,从而依赖库都有了 本php7是编译成fpm-php 使用的, 如果是apache那么 ...
- iOS sqlite数据库图像化查看
问题描述:在xocde上用sqlite数据库的时候,因为没有图形化界面,有些时候很难看出自己设计的数据库是否有问题,比如我刚上手sqlite数据库设计id为自增长时,很自然的用了identify(1, ...
- bootstrap - 响应式标题栏
先要拆分: .navbar 先变成相对定位 设置最小高度为50px: 设置底部边距为20px 然后设置一个 透明边框! 边框倒角 4px //@media (min-width:768px) - ...
- Unity3D 解决用Unity导出的Android工程在6.0及以上设备会弹出一串权限对话框的问题
解决用Unity导出的Android工程在6.0及以上设备会弹出一串权限对话框的问题 <meta-data android:name="unityplayer.SkipPermissi ...
- DevExpress 程序运行后 layoutView 卡片大小发生变化
设置属性前效果: 将layoutView1.CardMinSize 的属性更改为(0, 0) 后 效果:
- Home 安转beta版软件
今天想装测试版的cocoapods,用 brew install cocoapods 后,总是安装稳定版,就是1.1.0,不是最新的beta版,发现用下面这个命令可以装最新beta版 brew ins ...
- windows下nginx安装、配置与使用(转载)
目前国内各大门户网站已经部署了Nginx,如新浪.网易.腾讯等:国内几个重要的视频分享网站也部署了Nginx,如六房间.酷6等.新近发现Nginx 技术在国内日趋火热,越来越多的网站开始部署Nginx ...
- Ubuntu16.04安装有道词典
1.首先需要安装依赖包gstreamer0.10-plugins-ugly_0.10.19-2.1_amd64.deb,但是该依赖包 仍有两个依赖包需要提前安装,这三个依赖包都可以从这里下载 下载之后 ...
- myeclipse中如何修改项目的名称
第一种:myeclipse通用版 1.打比方,比如复制一个现有的项目,重命名项目名称,这里举例名称重新命名为"劳黑炭" 2.要清楚的是,这里的项目名称重新命名了,但是Web项目本 ...
- extarea输入的换行在网页上正常显示
如图