jquery源码分析之jQuery缓存处理
jquery框架在实现过程中对性能优化也做了很多处理,其中使用缓存就是重要的性能优化手段。
实现原理是从对象属性中取值,如果取值为undefined,则为此对象属性赋值,如果取值不为undefined,则直接返回,这样当在页面多次取对象属性值时,可以直接返回之前设置值,避免重复赋值,从而提高页面性能。如下代码模拟jQeruy实现了缓存方法
function TestCache() { } TestCache.prototype = { cache: function(owner) { var value = owner["cache"]; if (!value) { value = {}; owner["cache"] = value; } return value; } };
使用缓存
var testCache = new TestCache(); var owner = {}; // 第一次从缓存取值,缓存不存在,则初始化 var noCache = testCache.cache(owner); // 给缓存返回值进行赋值 noCache["name"] = "zhangsan"; noCache["age"] = 28; noCache["handle"] = function() { alert(this.name + "---" + this.age); }; } // 第二次从缓存取值,直接获取 var useCache = testCache.cache(owner); useCache.handle();
jQuery缓存实现
function Data() { this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; Data.prototype = { ... // 提供缓存方法 cache: function( owner ) { // We can accept data for non-element nodes in modern browsers, // but we should not, see #8335. // Always return an empty object. if ( !acceptData( owner ) ) { return {}; } // Check if the owner object already has a cache // 从对象属性中取缓存值 var value = owner[ this.expando ]; // If not, create one // 如果不存在,则创建 if ( !value ) { value = {}; // We can accept data for non-element nodes in modern browsers, // but we should not, see #8335. // Always return an empty object. if ( acceptData( owner ) ) { // If it is a node unlikely to be stringify-ed or looped over // use plain assignment if ( owner.nodeType ) { // 向对象属性赋值,即缓存了value对象 owner[ this.expando ] = value; // Otherwise secure it in a non-enumerable property // configurable must be true to allow the property to be // deleted when data is removed } else { Object.defineProperty( owner, this.expando, { value: value, configurable: true } ); } } } // 返回缓存值 return value; }, // 通过get方法取得缓存对象 get: function( owner, key ) { return key === undefined ? this.cache( owner ) : owner[ this.expando ] && owner[ this.expando ][ key ]; }, ... } // 实例化Data对象 var dataPriv = new Data();
在jQuery.event.add方法中初始化缓存对象
jQuery.event = { ... add: function( elem, types, handler, data, selector ) { // 从缓存中获取对象,如果缓存中不存在,则初始化缓存对象 var elemData = dataPriv.get( elem ); // 以下对缓存对象进行属性增强 if ( !( events = elemData.events ) ) { events = elemData.events = {}; } if ( !( eventHandle = elemData.handle ) ) { eventHandle = elemData.handle = function( e ) { ... } } ... while ( t-- ) { ... // handleObj is passed to all event handlers handleObj = jQuery.extend( { type: type, origType: origType, data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test( selector ), namespace: namespaces.join( "." ) }, handleObjIn ); if ( !( handlers = events[ type ] ) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; } handlers.push( handleObj ); ... } } ... }
在jQuery.event.dispatch方法中使用缓存
jQuery.event = { ... dispatch: function( event ) { // 取出缓存值,"events"属性是通过jQuery.event.add方法中对缓存对象进行了属性增强而得到 var handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], ... } ... }
相关推荐
瓜牛呱呱 2020-11-12
柳木木的IT 2020-11-04
yifouhu 2020-11-02
lei0 2020-11-02
源码zanqunet 2020-10-28
源码zanqunet 2020-10-26
一叶梧桐 2020-10-14
码代码的陈同学 2020-10-14
lukezhong 2020-10-14
lzzyok 2020-10-10
anchongnanzi 2020-09-21
clh0 2020-09-18
changcongying 2020-09-17
星辰大海的路上 2020-09-13
abfdada 2020-08-26
mzy000 2020-08-24
shenlanse 2020-08-18
zhujiangtaotaise 2020-08-18
xiemanR 2020-08-17