分析jq中缓存的案例

本文通过对jQuery-1.11.1.js源码的分析,揭示了jQuery如何实现数据缓存。通过一个简单的代码案例,阐述了缓存的本质——键值对结构,并利用JavaScript闭包保护缓存数据。同时,讨论了在缓存数据达到一定规模时,如何进行数据清理。最后,对原有的缓存函数进行了优化,使读取更加便捷。尽管有所简化,但仍然体现出jQuery缓存设计的巧妙。

分析jq中缓存的案例

jQuery流行框架在程序界还是非常火的,下面我们通过扒开jquery-1.11.1.js 的源码,来分析它是如何实现一些数据缓存的。

下面就是jQuery里头的createCache的源码,

/**
 * Create key-value caches of limited size
 * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
 *  property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
 *  deleting the oldest entry
 */
function createCache() {
    var keys = [];

    function cache( key, value ) {
        // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
        if ( keys.push( key + " " ) > Expr.cacheLength ) {
            // Only keep the most recent entries
            delete cache[ keys.shift() ];
        }
        return (cache[ key + " " ] = value);
    }
    return cache;
}

一时间是不是看的有点晕呢?我试着从最基本的代码案例来推演出这个案例,毕竟这个缓存案例还是非常精炼的。

首先要搞明白以下三点

  1. 缓存到底存的是啥,它存的就是键值对的结构。
  2. 为了保护缓存数据,我们采用js 里的闭包结构
  3. 在实际开发中,缓存的数据范围必须是有限的。所以要在缓存数据满之前对比较早的缓存数据进行删除操作。

所以我将代码写出如下:

var createCache = function(){
    var internalCache = {};  //用于缓存数据
    var arr = [];  //用于缓存数据的key 值
        //return 一个函数 ,这个典型的闭包结构
    return function ( k, v ) {
        // 判断是否传入第二个参数,有代码缓存数据, 如果只有一个数据 ,代表读取数据
        if ( v ) {
                //保证缓存数据中不存在的数据才进行缓存
            if ( !internalCache[ k ] ) {
                //假设缓存的数据长度是4  ,大于则进行删除操作 
                if ( arr.length > 3) {
                    // 删除最早的一个数据  
                    // shift  是数组中的方法,代码删除第一个数组中的元素,返回删除的值
                    var deleteKey = arr.shift();
                    // 删除键值对
                    delete internalCache[ deleteKey ];
                }
                arr.push( k ); // 缓存中没有数据的时候才会加进去
            }
            internalCache[ k ] = v;
        } else {
            //返回读取的数据
            return internalCache[ k ];
        }
    };
};


var type2Cache = createCache();
//这个方法可以重复使用
var selectorCache = createCache();
        //可以单步调试验证一下
        type2Cache('name', 'jim');
        type2Cache('name', 'tom');
        type2Cache('age', 10 );
        type2Cache('gender', 'nan');
        type2Cache('math', 100 );
        type2Cache('english', 99);
        type2Cache('chinese', 120);

搞明白上面的这个例子,下面将上面函数进行一个优化

优化两点:

  1. 将键值对从模型从闭包中提取出来,放到函数名上,因为函数也是对象。

  2. 将数据存到函数上后,那么读取数据就可以用函数名[ key ] 的方式。这就表明函数体可简化。

    var createCache = function(){
                var arr = [];
                var cache = function ( k, v ) {
                    //长度可以改成变量,这里为了验证就用具体数值了
                    if ( arr.length >= 3 ) {
                        // 删除
                        delete cache[ arr.shift() ];
                    }
    
                    // 加引号的目的是为了将k 转成字符串  ,同时防止 键值是 null 和undefined的情况
                    arr.push( k + "" ); // 缓存中没有数据的时候才会加进去
                    // 直接将数据存储到函数上
                    cache[ k + "" ] = v;
    
                };
                return cache;
            };
    
            var c = createCache();
            c('name1', 'jim');
            var v = c[ 'name1' ];
            console.log( c['age'] );
            console.log( c['name1'] );
    
    
            var v = c( 'k', 'v' );
    

写了这么多,其实还是有差别的。
不过各有优缺点吧;

 //jq 的优势:它可以采用如下的方式进行设置和读取,即有则读,无则存,再读
var data = cache[ key ] || cache( key, value );


// 而我的变式确要这样写。。
var data;
if ( cache[ key ] ) {
    date = cache[ key ];
} else {
    cache( key, value );
    data = value;
}
// 使用

jQuery写的很精炼,要学习的还要很多,加油吧。

                            by Turbo  beijing 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值