您的位置:首页 > Web前端 > JQuery

jQuery在去除缓存数据的一个失误

2009-12-14 13:45 211 查看
如果独自放着jQuery做事,它绝对做得很好,但jQuery充许与其他库共存在,有些事就防不胜防了。看下面代码,

data :function (elem, name,data){
//略
},
removeData: function (elem, name) {
elem = elem == window ? windowData : elem;

var id = elem[expando];

// If we want to remove a specific section of the element's data
if (name) {
if (jQuery.cache[id]) {
    //★★★★★★★
// Remove the section of cache data
delete jQuery.cache[id][name];

// If we've removed all the data, remove the element's cache
name = "";

for (name in jQuery.cache[id])
break;

if (!name) jQuery.removeData(elem);
    //★★★★★★★
}

// Otherwise, we want to remove all of the element's data
} else {
// Clean up the element expando
try {
delete elem[expando];
} catch(e) {
// IE has trouble directly removing the expando
// but it's ok with using removeAttribute
if (elem.removeAttribute) elem.removeAttribute(expando);
}

// Completely remove the data cache
delete jQuery.cache[id];
}
},

留意星号包围的区域,John Resig的想法是,如果把元素节点的对应的缓存体的键值对全部移除后,就把此缓存体从cache中去掉。举个通俗的例子,cache就是一家银行,页面上的元素节点(elem)就是一个个人,每个人可以通过data方法在银行里开个帐户(id),而存折就是elem的那个expando属性,这个帐户可以做存许多东西,每样东西都分开管理的,如果帐户里面的东西都取光就会自动注销这个帐户。嗯,本来就应该这样,没用的东西就应该收CG回收掉,节省内存。

下面是一个仿制品

//Object.prototype.aa = "司徒正美";
var a = '',
cache = { };//银行
cache.account = {};//其中一个空帐户
for(a in cache.account){
break;
}
//如果account里面还有其他东西,a就会置换成其他字符串,无法执行括号里的操作
alert(a)
if(!a){
alert("以下将执行注销操作!")
delete cache.account
}
//下面检测cache还有没有account这个属性
alert(cache.account)

运行代码

但如果jQuery与一些在Object原型进行了扩展的库共库呢?假设在它里面添加了个aa属性……

Object.prototype.aa = "司徒正美";
var a = '',
cache = { };//银行
cache.account = {};//其中一个空帐户
for(a in cache.account){
break;
}
//如果account里面还有其他东西,a就会置换成其他字符串,无法执行括号里的操作
alert(a)
if(!a){
alert("以下将执行注销操作!")
delete cache.account
}
//下面检测cache还有没有account这个属性
alert(cache.account)

运行代码

这时就无法清除缓存体了,遇到这篇文章提到的问题《Google Closure: 糟糕的JavaScript》,真是百密一疏!这也很好的教训了我们不要对Object.prototype这个最基本的东西做扩展,Prototype最近的版本也对此做了修正。那么如何排除干扰呢?

Object.prototype.aa = "司徒正美";
var a = '',
cache = { };//银行
cache.account = {};//其中一个空帐户
for(var key in cache.account ){
if (cache.account.hasOwnProperty(key)) {
a = key
}
}
//如果account里面还有其他东西,a就会置换成其他字符串,无法执行括号里的操作
alert(a)
if(!a){
alert("以下将执行注销操作!")
delete cache.account
}
//下面检测cache还有没有account这个属性
alert(cache.account)

运行代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: