第十七课:数据缓存系统

这一章主要讲的是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就可以了。非常方便。但是兼容性就不容乐观了。

这是新技术,了解就行。

总结:

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

加油!

时间: 2024-10-10 20:07:57

第十七课:数据缓存系统的相关文章

jQuery.data的是jQuery的数据缓存系统

jQuery.Data源码 jQuery.data的是jQuery的数据缓存系统.它的主要作用就是为普通对象或者DOM元素添加数据. 1 内部存储原理 这个原理很简单,原本要添加在DOM元素本身的数据,现在被集中的存储在cache集合中.它们之间靠一个从1开始的数字键来联系着.这样DOM元素就不会像以前那么笨重了,更不会出现以前那种循环引用而引起的内存泄漏.现在DOM只需要保存好这个数字键值即可.这个属性值被保存在DOM元素的一个属性里,该属性名是由jQuery.expando生成的. 2 Da

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

Memcache,Redis,MongoDB(数据缓存系统)方案对比与分析 数据库表数据量极大(千万条),要求让服务器更加快速地响应用户的需求. 二.解决方案: 1.通过高速服务器Cache缓存数据库数据 2.内存数据库 (这里仅从数据缓存方面考虑,当然,后期可以采用Hadoop+HBase+Hive等分布式存储分析平台) 三.主流解Cache和数据库对比: 上述技术基本上代表了当今在数据存储方面所有的实现方案,其中主要涉及到了普通关系型数据库(MySQL/PostgreSQL),NoSQL数据

jQuery源码解读 - 数据缓存系统:jQuery.data

jQuery在1.2后引入jQuery.data(数据缓存系统),主要的作用是让一组自定义的数据可以DOM元素相关联——浅显的说:就是让一个对象和一组数据一对一的关联. 一组和Element相关的数据如何关联着这个Element一直是web前端的大姨妈,而最初的jQuery事件系统照搬Dean Edwards的addEvent.js:将回调挂载在EventTarget上,这样下来,循环引用是不可忽视的问题.而在web前端中,数据和DOM的关系太过基情和紧张,于是jQuery在1.2中,正式缔造了

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

mongodb和memcached不是一个范畴内的东西.mongodb是文档型的非关系型数据库,其优势在于查询功能比较强大,能存储海量数据.mongodb和memcached不存在谁替换谁的问题. 和memcached更为接近的是redis.它们都是内存型数据库,数据保存在内存中,通过tcp直接存取,优势是速度快,并发高,缺点是数据类型有限,查询功能不强,一般用作缓存.在我们团队的项目中,一开始用的是memcached,后来用redis替代. 相比memcached: 1.redis具有持久化机

jQuery 2.0.3 源码分析 数据缓存

转载http://www.cnblogs.com/aaronjs/p/3370176.html 历史背景: jQuery从1.2.3版本引入数据缓存系统,主要的原因就是早期的事件系统 Dean Edwards 的 ddEvent.js代码 带来的问题: 没有一个系统的缓存机制,它把事件的回调都放到EventTarget之上,这会引发循环引用 如果EventTarget是window对象,又会引发全局污染 不同模块之间用不同缓存变量 一般jQuery开发,我们都喜欢便捷式的把很多属性,比如状态标志

缓存系统的决策:什么数据要缓存?什么缓存数据要丢给业务?

App进入页面请求服务器,在数据返回之前,没什么给用户看,所以我们用一种缓存系统来保存上次请求的数据,这次进入的时候先把缓存数据绘制到UI上,让用户先看到整个页面布局和可能过时的数据,等网络数据返回后再刷新一遍页面,以此来提高用户体验.那么就带来两个问题: 1, 什么样的数据应该缓存起来? 2, 什么情况下应该把缓存数据丢给业务?什么情况下不可以? 总结一下: 1, 什么样的数据应该缓存起来?先说不应该缓存的数据,包括: a. 提交类的接口返回数据,缓存的目的是为了填充页面UI元素防止白页,提交

大型web系统数据缓存设计

1. 前言 在高访问量的web系统中,缓存几乎是离不开的:但是一个适当.高效的缓存方案设计却并不容易:所以接下来将讨论一下应用系统缓存的设计方面应该注意哪些东西,包括缓存的选型.常见缓存系统的特点和数据指标.缓存对象结构设计和失效策略以及缓存对象的压缩等等,以期让有需求的同学尤其是初学者能够快速.系统的了解相关知识. 2. 数据库的瓶颈 2.1 数据量 关系型数据库的数据量是比较小的,以我们常用的MySQL为例,单表数据条数一般应该控制在2000w以内,如果业务很复杂的话,可能还要低一些.即便是

ecshop二次开发系统缓存优化之扩展数据缓存的必要性与方法

1.扩展数据缓存的必要性 大家都知道ecshop系统使用的是静态模板缓存,在后台可以设置静态模板的缓存时间,只要缓存不过期,用户访问页面就相当于访问静态页面,速度可想而知,看似非常完美,但是ecshop 有一个方法被滥用了,那就是 clear_cache_files() ,该方法会把整个系统的静态模板都清除掉,商家或者系统后台管理员只要在后台修改一下商品,或者修改个其他的东西,就会调用该方法将所有静态缓存都清掉,所以如果有商家频繁的修改商品,那么静态模板缓存其实是形同虚设,系统每次都会重新执行动

NeHe OpenGL教程 第四十七课:CG顶点脚本

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第四十七课:CG顶点脚本 CG 顶点脚本 nVidio的面向GPU的C语言,如果你相信它就好好学学吧,同样这里也只是个入门.记住,类似的语言还有微软的HLSL,OpenGL的GLSL,ATI的shaderMonker.不要选错哦:)