这一章主要讲的是jQuery的缓存系统的历史发展,以及他自己的框架的缓存系统的实现。都是源码解析。

我就挑几个重点讲下:

(1)jQuery的缓存机制的原理

jQuery的缓存机制实现的原理是在元素中添加自定义属性,然后把这个自定义属性赋值为uid,而这个uid就在jQuery的cache对象中的一个属性(唯一的),这个唯一的属性其实是一个对象,这个对象里面存储的就是你给这个元素添加的数据。

举个例子:

<input id="chaojidan" name="chaojidan" >

<input id="chaojidan1" name="chaojidan1" >

$("#chaojidan").data({name:"chaojidan",age:"25"});

执行这个语句后,

<input id="chaojidan" name="chaojidan"  自定义属性(jQuery版本+随机数) = uid(1,一个从0开始累加的整数)>

在jQuery中,$.cache = {1: { name:"chaojidan",age:"25"  }}

当给第二个input添加数据时,

$("#chaojidan1").data({name:"chaojidan1",age:"26"});

执行这个语句后,

<input id="chaojidan1" name="chaojidan1"  自定义属性(jQuery版本+随机数) = uid(2,一个从0开始累加的整数)>

在jQuery中,$.cache = {  1: { name:"chaojidan",age:"25"  }, 2: { name:"chaojidan1",age:"26"  }}

取数据时,会先在元素中查找自定义属性的值(uid),然后再去$.cache对象中查找uid,得到之前存储的数据,最后通过需要取得什么数据的key值,返回value值。

(2)兼容性问题

在旧版本IE中,元素节点(object,embed,applet)只是COM的包装,一旦引入资源后,它就会变成那种资源的实例。一旦这资源是由VB等语言编写,由于VM有严格的访问控制,不能随便给对象添加新属性和方法,就会出现无法使用jQuery缓存系统。

HTML5新增了一种data-*的缓存机制,当用户在元素上设置了data-开头的属性时,它们的值会保存在元素节点的dataset对象上。但是它只支持字符串(以防循环引用)。

这里我说下循环引用的实例:

input.moneySet = { fangzi:"shenzhen",ele:input}

元素节点input有一个自定义属性是moneySet,它的值是一个对象,如果是一个字符串,永远都不会循环引用。由于是一个对象,对象中有一个ele属性,这个属性刚好又指向input元素。这时就出现了循环引用的状态。

(3)新一代的jQuery缓存机制实现原理

它是通过对valueOf方法重写,并通过Object.defineProperty方法操作实现的,这套缓存系统不支持IE8以及以下版本浏览器。

实现原理:对每一个实例(调用jQuery缓存系统中data方法的任何东西),调用valueOf方法,并传入jQuery中的Data类,如果返回object,就证明valueOf方法没重写,我们就通过Object.defineProperty重写它的valueOf方法。如果返回string,则已经被重写了,就不用再次重写。

Object.defineProperty(目标对象,要定义的属性或者方法名,目标属性所拥有的特性)

Object.defineProperty(目标对象,"valueOf",{   value:function(){ return value1} //writable    ,configurable, enumerable内部属性 ),这句代码的意思就是,目标元素的valueOf方法被重写了,它的valueOf方法的值是value1,同时还可以设置valueOf是否可以被遍历,被重写,被重新定义。默认情况下是不能的。如果你在里面写了writable:true,那么目标对象的valueOf就是可重写的。

以上方法,还有内部属性,在js高级程序设计里面有详解。但是实际项目中用的比较少,作为了解就行。如果是开发移动端,还是推荐去精读的。

(4)ECMAScript6新特性创建的缓存系统

之前的缓存系统都是通过唯一的一个ID,来建立目标对象(元素节点)与缓存体(缓存系统Cache)之间的连接。而ES6中有一个新的集合对象WeakMap。

WeakMap是个什么样的对象呢,平时,我们的js对象,键名name只能是字符串,键值key任意。我们可以通过for in循环遍历它的所有键值对。而WeakMap的键名name只能为一个非null的对象,键值key任意。我们无法通过for in循环遍历它里面的键值对,读写或删除只能对它暴露的接口进行。它目前只有四个方法:set,get,has,delete。

举个例子:

var map = new WeakMap();

el = document.body;

map.set(el,{data:{}});  //设置键值对

var value = map.get(el);   //读取目标值

console.log(value)     //{data:{}}

console.log(map.has(el))   //是否有此键名name,这里是true

map.delete(el)    //删除键值对。如果作为键名的对象el被删除,那么它对应的缓存体(el:{data:{}})会自动被清除出WeakMap对象。

因此通过此对象很容易实现缓存系统。大家都知道,我们的目标元素不过是元素节点,document对象,window对象,完全可以做为WeakMap的键名。我们可以把缓存仓库改成一个WeakMap实例。我们不再需要用唯一的id来作为桥梁关联两者。只需要map.set方法就可以建立关联了。判定目标元素是否关联着缓存体,只需要用map.has方法。删除缓存体用map.delete就可以了。非常方便。但是兼容性就不容乐观了。

这是新技术,了解就行。

总结:

数据缓存其实就是在目标元素与缓存体之间建立一对一的关系,然后在缓存体上操作数据。

加油!

转载于:https://www.cnblogs.com/chaojidan/p/4151456.html

第十七课:js数据缓存系统的原理相关推荐

  1. Memcached 数据缓存系统

    Memcached 数据缓存系统 常用命令及使用:http://www.cnblogs.com/wayne173/p/5652034.html Memcached是一个自由开源的,高性能,分布式内存对 ...

  2. Memcache,Redis,MongoDB(数据缓存系统)方案对比与分析

    一.问题:     数据库表数据量极大(千万条),要求让服务器更加快速地响应用户的需求. 二.解决方案:      1.通过高速服务器Cache缓存数据库数据      2.内存数据库   (这里仅从 ...

  3. Memcached和Redis数据缓存系统

    1.1 Memcached介绍 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态.数据库驱 ...

  4. 分布式缓存系统Redis原理解析

    Redis作为内存数据库已经广泛应用于大数据领域,已经成为分布式架构下的基础组件.本文主要介绍了Redis内部的实现原理包括IO模型.内存管理.数据持久化等以及三种集群架构,旨在了解其中的实现机制. ...

  5. web-storage-cache 使用JS数据缓存

    https://github.com/WQTeam/web-storage-cache 使用WebStorageCache,只要在页面上引入下面代码即可. <script src="s ...

  6. 第十七课,帧缓存(后期处理)

    反向 void main() {FragColor = vec4(vec3(1.0 - texture(screenTexture, TexCoords)), 1.0); } 灰度 均分灰度 void ...

  7. 大数据学习的第一课-大数据概论和技术原理

    目录 大数据概论 大数据概念 为什么会有大数据 大数据的4v特征 大数据的来源 云计算与大数据 大数据发展历史 大数据技术原理 大数据的存储技术 大数据的计算技术 数据分析技术 Hadoop生态圈 大 ...

  8. 一款暴涨的全新缓存系统,让 Redis 气急败坏回击

    回击就代表输了?! 今年年中,一位前谷歌.前亚马逊的工程师推出了他创作的开源内存数据缓存系统 Dragonfly,用 C/C++ 编写,基于 BSL 许可(Business Source Licens ...

  9. jQuery最核心的基础设施之一——数据缓存模块进化史

    数据缓存系统最早应该是jQuery1.2引入的,那时它的事件系统完成照搬DE大神的addEvent.js,而addEvent在实现有个缺憾,它把事件的回调都放到EventTarget之上,这会引发循环 ...

最新文章

  1. 关于肠道菌群研究的7大事实和5大倡议
  2. udp与tcp协议介绍
  3. 国家有线网挂牌时间再度推迟 预计为2012年底
  4. 剑指offer之把字符串里面空格替换成百分之20[时间复杂度是O(n)]
  5. @hot热加载修饰器导致static静态属性丢失(已解决)
  6. git ssh配置文件 服务器_【GIT】日常开发中的这些Git技巧你知道吗?
  7. 项目Beta冲刺(团队7/7)
  8. ​百度网盘下线SVIP免第三方广告特权;小米回应手机异常发热;Windows 11新应用商店将于6月24日亮相|极客头条...
  9. php往pdf模板添加数据,php实现往pdf中加数字签名操作示例【附源码下载】
  10. 基于Android-JavaEE-DB2实现的旧物交易平台
  11. 台式机未插入扬声器或者耳机
  12. matlab如何整理表格数据,数据整理的程序与步骤:包括数据预处理、分类或分组、图表显示...
  13. python中的utils模块_Python中的模块及扩展库
  14. nohup java -jar 命令启动jar包,项目仍然会莫名其妙挂掉的解决方法
  15. java 环境变量 locale_locale的设定及其LANG、LC_ALL、LANGUAGE环境变量的区别
  16. 一个例程学会使用——模糊逻辑工具箱
  17. 【开源教程11】疯壳·开源蓝牙心率防水运动手环-整机功能代码讲解
  18. BZOJ 2277 strongbox (gcd)
  19. com.github.pageHelper 用法
  20. forEach遍历数组

热门文章

  1. Java关键字介绍之final
  2. crysis3 android,Crytek谈安卓版《Crysis 3》:Tegra X1图形性能OK,瓶颈是CPU
  3. 批量探测工具fpingping常用命令集合大学霸IT达人
  4. Swift 1.1语言第7章 函数和闭包
  5. php时间戳 今天昨天,php求今天、昨天、明天时间戳的简单实现方法
  6. 解决Matplotlib图表不能在Pycharm中显示的问题:使用Anaconda
  7. 基于脑电图的情绪识别BCI应用于DOC患者
  8. Python-EEG工具库MNE中文教程(14)-Epoch对象中的元数据(metadata)
  9. 马斯克躺枪得州最严堕胎法案,因拒绝表态遭炮轰!“不站女权就抵制特斯拉”...
  10. 最新电子皮肤的触觉有多灵?连空气流动都能感受到