往期回顾:

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

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

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

源码链接:内附实例代码

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

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

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

 (function(window, undefined) {

     function jQuery(sel) {
return new jQuery.prototype.init(sel);
} jQuery.prototype = {
constructor: jQuery,
init: function(sel) {
if(typeof sel === 'string'){
var that = this;
var nodeList = document.querySelectorAll(sel);
Array.prototype.forEach.call(nodeList, function(val, i){
that[i] = val;
})
this.selector = sel;
this.length = nodeList.length;
}
}
} jQuery.prototype.init.prototype = jQuery.prototype; window.$ = jQuery; function Data() {
this.uid = 1;
//原来是防篡改对象(简化一下)
this.cache = {};
this.expando = 'jQuery' + Math.random();
} Data.prototype = {
//获取elem的uid值
key: function(elem) { var uid = elem[this.expando];
if(!uid) {
//为elem分配一个uid
uid = this.uid++;
elem[this.expando] = uid;
} if(!this.cache[uid]) {
this.cache[uid] = {};
} return uid;
},
set: function(elem, name, val) {
var cache = this.cache[this.key(elem)];
cache[name] = val;
},
get: function(elem, name) {
var cache = this.cache[this.key(elem)];
return cache[name];
}
} var data_user = new Data(); jQuery.prototype.data = function(name, val) {
if(val) {
Array.prototype.forEach.call(this, function(elem) {
data_user.set(elem, name, val);
})
return this;
}
else return data_user.get(this[0], name);
} })(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;

 key: function(elem) {

     var uid = elem[this.expando];
if(!uid) {
//为elem分配一个uid
uid = this.uid++;
elem[this.expando] = uid;
} if(!this.cache[uid]) {
this.cache[uid] = {};
} return uid;
}

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

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

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

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

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

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

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

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

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

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

 var data_user = new Data();

 jQuery.prototype.data = function(name, val) {
if(val) {
Array.prototype.forEach.call(this, function(elem) {
data_user.set(elem, name, val);
})
return this;
}
else return data_user.get(this[0], name);
}

最后,运行如代码:

$('#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上的数据;

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

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

    往期回顾: jQuery的XX如何实现?——1.框架 jQuery的XX如何实现?——2.show与链式调用 jQuery的XX如何实现?——3.data与cache机制 -------------- ...

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

    往期回顾: jQuery的XX如何实现?——1.框架 -------------------------- 源码链接:内附实例代码 jQuery使用许久了,但是有一些API的实现实在想不通.于是抽空看 ...

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

    源码链接:内附实例代码 jQuery使用许久了,但是有一些API的实现实在想不通.于是抽空看了jQuery源码,现在把学习过程中发现的一些彩蛋介绍给大家(⊙0⊙). 下面将使用简化的代码来介绍,主要关 ...

  4. jquery在元素中存储数据:data()

    转自:http://www.php.cn/js-tutorial-405445.html 在元素中存储数据:data() 1 2 3 4 5 6 7 8 9 10 <!DOCTYPE html& ...

  5. org.springframework.data.redis.cache.RedisCacheManager

    org.springframework.data.redis.cache.RedisCacheManager

  6. 判断和调整library cache,data dictionary cache,buffer cache性能

    Oracle SGA是oracle的内存结构,存放着oracle通过oracle进程读写的内存数据.sga分为好多组件,比如shared pool,buffer cache,redo log buff ...

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

    .attr(),此方法从jq1.0开始一直存在,官方文档写的作用是读/写DOM的attribute值,其实1.6之前有时候是attribute,有时候又是property..prop(),此方法jq1 ...

  8. jquery方法详解--bind(type, [data], fn)

    转自:http://www.zhufengpeixun.cn/jquery/bind_type_data_fn.html bind(type, [data], fn)  返回值::jQuery 概述 ...

  9. jquery中attr、prop、data

    在高版本的jquery中获取标签的属性,可以使用attr().prop().data(),那么这些方法有什么区别呢? 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法. 对于HTML元 ...

随机推荐

  1. Modbus协议

    总体上来说,发送命令格式如下:模块号(1字节)功能码 起始地址(2字节)   数据(X字节) CRC(2位) 模块号(1字节)功能码(要读取的寄存器,读 01,设置05,Coil Status/Inp ...

  2. C#连接数据库的四种方法

    在进行以下连接数据库之前,请先在本地安装好Oracle Client,同时本次测试System.Data的版本为:2.0.0.0. 在安装Oracle Client上请注意,如果OS是3-BIT请安装 ...

  3. Maven-3.2.2安装配置

    (1)安装JDK,这里是1.7.0_51 (2)Maven-3.2.2下载地址:http://mirrors.cnnic.cn/apache/maven/maven-3/3.2.2/binaries/ ...

  4. pickle

    [pickle] Python提供了pickle模块来实现序列化. 首先,我们尝试把一个对象序列化并写入文件: pickle.dumps()方法把任意对象序列化成一个bytes,然后,就可以把这个by ...

  5. Python基础(七)内置函数

    今天来介绍一下Python解释器包含的一系列的内置函数,下面表格按字母顺序列出了内置函数: 下面就一一介绍一下内置函数的用法: 1.abs() 返回一个数值的绝对值,可以是整数或浮点数等. 1 2 3 ...

  6. 51单片机ALE引脚的控制(摘录)

    ALE/PROG: 当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节. 在FLASH编程期间,此引脚用于输入编程脉冲. 在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频 ...

  7. Android广播错误.MainActivity$MyReceiver; no empty constructor

    广播的定义,如果是内部类,必须为静态类. 下面总结一下作为内部类的广播接收者在注册的时候需要注意的地方:   1.清单文件注册广播接收者时,广播接收者的名字格式需要注意.因为是内部类,所以需要在内部类 ...

  8. oracle 驱动安装备忘

    ubuntu 从oracle官网下载两个必须的rpm包(这里选择的是version12.1.0.2.0, 64位操作系统) oracle-instantclient12.1-basic-12.1.0. ...

  9. Python.Scrapy.12-scrapy-source-code-analysis-part-2

    Scrapy 源代码分析系列-2 signals, signalmanager, project, conf 1. 模块: signals.py signalmanager.py project.py ...

  10. 《Java程序设计》课程准备之问卷调查

    一.你对自己的未来有什么规划?做了哪些准备? 答:未来就是找个好工作,在保证自己与父母生活条件良好的基础上,进一步的提高精神上的需求.如:旅游度假,支持更多业余爱好等.准备就是:好好学习,好好运动,好 ...