分析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;
}
一时间是不是看的有点晕呢?我试着从最基本的代码案例来推演出这个案例,毕竟这个缓存案例还是非常精炼的。
首先要搞明白以下三点
- 缓存到底存的是啥,它存的就是键值对的结构。
- 为了保护缓存数据,我们采用js 里的闭包结构
- 在实际开发中,缓存的数据范围必须是有限的。所以要在缓存数据满之前对比较早的缓存数据进行删除操作。
所以我将代码写出如下:
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);
搞明白上面的这个例子,下面将上面函数进行一个优化
优化两点:
将键值对从模型从闭包中提取出来,放到函数名上,因为函数也是对象。
将数据存到函数上后,那么读取数据就可以用函数名[ 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