一、常见内存问题
浏览器才用自动垃圾回收方法,但是浏览器垃圾回收方法都有bug,会产生内存泄漏。
1.常见的内存泄漏
1).循环引用
2).函数闭包
3).DOM插入
2.一个DOM对象被其他的javascript对象引用,与此同时,又引用同一个或者其他的javascript对象
第一种:多个对象循环引用
var a = new Object;
var b = new Object;
a.r = b;
b.r = a;
第二种:循环引用自己
var a = new Object;
a.r = a;
// 其实上面的Object对象互相引用是无害的,但是当把这些对象转换成javascript的DOM对象,就会发生内存泄漏
3.总结
js的内存泄漏,无外乎就是从DOM中remove,但是当有变量或者对象引用这个DOM对象,那么内存中就无法删除,使得浏览器的内存占用居高不下。这种占用内存,需要刷新页面才能释放。
另外一种情况,一个DOM对象和Js对象互相引用,这样就造成严重的内存泄漏,即使刷新浏览器也无法释放内存。这就是严格意义上的内存泄漏
4.解决方法
由于DOM元素也是对象,所以我们可以直接扩展DOM属性,但是给DOM对象添加自定义属性和过多的对象,就可能导致内存泄漏。所以应该避免这样做,因此最好的解决方法就是采用一种低耦合的方式,让DOM和缓存数据结合起来。
二、缓存对设计思路
jQuery缓存设计接口对数据处理有以下几种:
用name和value为对象附加数据
一个对象为一个对象附加数据
为DOM元素附加数据
数据缓存设计的关键就是:
数据放在内存中,通过一个映射关系与直接的DOM元素发生关联
1.dom元素,数据储存在jQuery.cache中
2.普通的js对象,数据储存在该对象中
所以,首先要在内存中开辟一个区域,jQuery用的是cache对象,那么所有的数据处理,无非就是对jQuery.cache对象的curd操作了
1.如果是DOM元素,通过分配一个唯一的id使DOM对象和缓存的数据关联起来,关联的id被附加到jQuery.expando对象上,数据储存在全局缓存对象jQuery对象上,在增删改查的时候,通过关联id从jQuery.cache中找到对应数据
2.如果是javascript对象,数据则直接储存在改对象的属性jQuery.expando,curd的时候,则是对javascript对象的数据缓存对象执行相应操作
3.为了避免jQuery内部使用的数据和用户自定义的数据发生冲突,缓存对象把内部数据储存在数据缓存对象上,把自定义数据数据储存在数据缓存属性的data上面
所以,jQuery在数据缓存处理抽出一个data类来做不同的数据处理
var data_priv = new Data(); // 内部使用,比如数据对象,queue,Deferred,事件,动画缓存
var data_user = new Data(); // 开发者使用,比如$.attr(),$.data等
三、Data类等设计
我们看看Data类是如何构建数据缓存池的
1.先在jQuery内部创建一个cache()对象,用来保存缓存数据,然后忘需要进行缓存的DOM节点上面扩展一个为expando的属性
function Data(){
Object.defineProperty(this.cache = {},{
get: function(){
return {};
},});
this.expando = jQuery.expando + Math.random();
};