zoukankan      html  css  js  c++  java
  • 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上的数据;

  • 相关阅读:
    初识ambari
    MySQL Split 函数
    行存储和列存储
    Hbase安装和错误
    mysql 常用自定义函数解析
    mysq l错误Table ‘./mysql/proc’ is marked as crashed and should be repaired
    MySql提示:The server quit without updating PID file(…)失败
    mysql 自定义函数
    hive 调优总结
    [css] line boxes
  • 原文地址:https://www.cnblogs.com/jiahuix/p/5483410.html
Copyright © 2011-2022 走看看