jQuery的XX如何实现?——3.data与cache机制

往期回顾:

jQuery的XX如何实现?——1.框架

jQuery的XX如何实现?——2.show与链式调用

--------------------------

源码链接:内附实例代码

jQuery使用许久了,但是有一些API的实现实在想不通。于是抽空看了jQuery源码,现在把学习过程中发现的一些彩蛋介绍给大家(⊙0⊙)。

下面将使用简化的代码来介绍,主要关注jQuery的实现思想~>_<~

相较于第一篇(与第二篇无相关性),代码更新了:27~71

 1 (function(window, undefined) {
 2
 3     function jQuery(sel) {
 4         return new jQuery.prototype.init(sel);
 5     }
 6
 7     jQuery.prototype = {
 8         constructor: jQuery,
 9         init: function(sel) {
10             if(typeof sel === ‘string‘){
11                 var that = this;
12                 var nodeList = document.querySelectorAll(sel);
13                 Array.prototype.forEach.call(nodeList, function(val, i){
14                     that[i] = val;
15                 })
16                 this.selector = sel;
17                 this.length = nodeList.length;
18             }
19         }
20     }
21
22     jQuery.prototype.init.prototype = jQuery.prototype;
23
24     window.$ = jQuery;
25
26
27     function Data() {
28         this.uid = 1;
29         //原来是防篡改对象(简化一下)
30         this.cache = {};
31         this.expando = ‘jQuery‘ + Math.random();
32     }
33
34     Data.prototype = {
35         //获取elem的uid值
36         key: function(elem) {
37
38             var uid = elem[this.expando];
39             if(!uid) {
40                 //为elem分配一个uid
41                 uid = this.uid++;
42                 elem[this.expando] = uid;
43             }
44
45             if(!this.cache[uid]) {
46                 this.cache[uid] = {};
47             }
48
49             return uid;
50         },
51         set: function(elem, name, val) {
52             var cache = this.cache[this.key(elem)];
53             cache[name] = val;
54         },
55         get: function(elem, name) {
56             var cache = this.cache[this.key(elem)];
57             return cache[name];
58         }
59     }
60
61     var data_user = new Data();
62
63     jQuery.prototype.data = function(name, val) {
64         if(val) {
65             Array.prototype.forEach.call(this, function(elem) {
66                 data_user.set(elem, name, val);
67             })
68             return this;
69         }
70         else return data_user.get(this[0], name);
71     }
72
73
74 })(window);

--------------------------

cache在jQuery中的作用:为dom分配一个存储空间。简而言之,就是为了保存数据(⊙0⊙),比如:

1.data API     2.事件队列

下面结合图片与代码来介绍cache与dom之间是如何建立联系的。

在图中可以看到,elem下有一个{jQueryXXX : cache.uid}的键值对。通过elem[Data.expando]可以获取到这个elem在Data下的cache.uid。有了cache.uid后,我们就可以取到elem在Data.cache中的数据。

有点绕,我们用伪代码整理一下:

var uid = elem[Data.expando];
var data = Data.cache[uid];

最后获取到的data就是elem在Data.cache中保存的数据╰( ̄▽ ̄)╮

--------------------------

好了,有了上面的思路,我们现在用js代码实现出来。

先介绍Data.prototype下的三个方法,有了这三个方法,后续的操作都会非常简便╰( ̄▽ ̄)╮

Data.prototype.key(获取elem的uid):

1.获取elem在Data.cache中的uid【38行】;

2.为新的elem在Data.cache中建立一个新的空间【39~47行】,并返回uid;

36 key: function(elem) {
37
38     var uid = elem[this.expando];
39     if(!uid) {
40         //为elem分配一个uid
41         uid = this.uid++;
42         elem[this.expando] = uid;
43     }
44
45     if(!this.cache[uid]) {
46         this.cache[uid] = {};
47     }
48
49     return uid;
50 }

Data.prototype.set(保存数据):

51 set: function(elem, name, val) {
52     var cache = this.cache[this.key(elem)];
53     cache[name] = val;
54 }

Data.prototype.get(读取数据):

55 get: function(elem, name) {
56     var cache = this.cache[this.key(elem)];
57     return cache[name];
58 }

三个函数实现完毕后,其实针对cache的操作就非常简便了。保存数据就调用set,读取数据就调用get。

--------------------------

接下来,利用cache机制来实现data API

//保存数据
$(‘#div‘).data(‘key1‘, 123);
//读取数据
$(‘#div‘).data(‘key1‘);

实现起来也非常简便,所以直接上代码,各位客官自己琢磨下了~>_<~+

代码的第66行就是保存数据,而第70行就是读取数据。

61 var data_user = new Data();
62
63 jQuery.prototype.data = function(name, val) {
64     if(val) {
65         Array.prototype.forEach.call(this, function(elem) {
66             data_user.set(elem, name, val);
67         })
68         return this;
69     }
70     else return data_user.get(this[0], name);
71 }

最后,运行如代码:

$(‘#div‘).data("num", 123);
$(‘#div‘).data("objVal", {val:123});
console.log($(‘#div‘).data("num"));
console.log($(‘#div‘).data("objVal"));

得到结果:

--------------------------

最后再唠叨几句:这里实现data API是非常简陋的~>_<~+。实际中:

1.jQuery会对data的name进行格式限制(比如data-*);

2.还能识别dom上的数据(比如<div data-haha="123"></div>);

3.elem被remove掉的时候,还会删除对应cache上的数据;

时间: 2024-08-26 00:16:20

jQuery的XX如何实现?——3.data与cache机制的相关文章

jQuery的XX如何实现?——4.类型检查

往期回顾: jQuery的XX如何实现?——1.框架 jQuery的XX如何实现?——2.show与链式调用 jQuery的XX如何实现?——3.data与cache机制 -------------------------- 源码链接:内附实例代码 jQuery使用许久了,但是有一些API的实现实在想不通.于是抽空看了jQuery源码,现在把学习过程中发现的一些彩蛋介绍给大家(⊙0⊙). 下面将使用简化的代码来介绍,主要关注jQuery的实现思想~>_<~ 相较于第一篇(与第二.三篇无相关性)

jQuery的XX如何实现?——1.框架介绍

源码链接:内附实例代码 jQuery使用许久了,但是有一些API的实现实在想不通.于是抽空看了jQuery源码,现在把学习过程中发现的一些彩蛋介绍给大家(⊙0⊙). 下面将使用简化的代码来介绍,主要关注jQuery的实现思想~>_<~ 1 //匿名立即执行函数 2 //1.防止污染全局空间 3 //2.选择性保护内部变量 4 (function(window, undefined){ 5 //第二参数undefined设置而不传的原因: 6 // 外部发生这种情况:var undefined

jquery源码之缓存系统--$.data

jQuery内置了一个缓存系统,它做的事情可就多了,动画模块,事件模块等非常有用的模块都是依赖它实现的. 其实说到底,就是在jQuery的命名空间下开辟了一个cache的对象. 将数据以一定得规则存放的cache对象中. 首先我们来看看内部实现: jQuery.extend({ cache: {}, deletedIds: [], // Remove at next major release (1.9/2.0) uuid: 0, // Unique for each copy of jQuer

jQuery的XX如何实现?——2.show与链式调用

往期回顾: jQuery的XX如何实现?——1.框架 -------------------------- 源码链接:内附实例代码 jQuery使用许久了,但是有一些API的实现实在想不通.于是抽空看了jQuery源码,现在把学习过程中发现的一些彩蛋介绍给大家(⊙0⊙). 下面将使用简化的代码来介绍,主要关注jQuery的实现思想~>_<~ 相较于上一篇,代码更新了:21~78 1 (function(window, undefined){ 2 3 function jQuery(sel){

jquery中attr、prop、data

在高版本的jquery中获取标签的属性,可以使用attr().prop().data(),那么这些方法有什么区别呢? 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法. 对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法. .data()看作是存取data-xxx这样DOM附加信息的方法 上面的描述也许有点模糊,举几个例子就知道了. <a href="http://www.baidu.com" target="_self"

javascript学习笔记-2:jQuery中$(&quot;xx&quot;)返回值探究

最近在写一个jQuery插件的时候,需要用到一个条件: 一组img标签,每一个元素都需要被它前面的元素值src替换,如果是第一个(序列为0)则其值为最后一个元素值,如果是最后一个,那么其值为第一个元素值,以此形成一个闭环. 为此,我使用了三元运算符?:,其表达式为:var next=$(this).next()?$(this).next():imageItems.first(); 运行测试发现如下问题,当运行到数组最后一个元素时,其next是始终不会是这一组img标签的第一个,为此对$(this

jQuery中attr()、prop()、data()用法及区别

.attr(),此方法从jq1.0开始一直存在,官方文档写的作用是读/写DOM的attribute值,其实1.6之前有时候是attribute,有时候又是property..prop(),此方法jq1.6引入,读/写DOM的property..data(),此方法在jq1.2.3引入,作用是把任意的值读取/存储到DOM元素对应的jq对象上. 从性能上对比,.prop() > .data() > .attr(),不同浏览器不同版本.data()和.attr()的性能关系有差异,不过.prop()

jQuery源码

/*! * jQuery JavaScript Library v1.8.3 * http://jquery.com/ * * Includes Sizzle.js * http://sizzlejs.com/ * * Copyright 2012 jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * * Date: Tue Nov 13 20

jQuery1.9.1源码分析--数据缓存Data模块

阅读目录 jQuery API中Data的基本使用方法介绍 jQuery.acceptData(elem)源码分析 jQuery.data(elem, name, data)源码分析 internalRemoveData方法源码分析 internalData方法的源码分析 jQuery.fn.extend({data: function( key, value ) {}})源码分析 jQuery.extend({removeData: function( elem, name ) {}})源码分