Brief analysis of jQuery's caching mechanism

  • 2020-03-30 03:17:44
  • OfStack

While studying jQuery's animation queue recently, I found that jQuery's cache system is also very powerful. Although I have touched on it before, I haven't studied it in depth. JQuery's caching system is relatively simple for external applications. For example, to store some URL data in the cache, just write like this:


var val = "stylechen.com";
$("div").data( "url" ); //Returns the undefined
$("div").data( "url", val ); //Return to "stylechen.com"
$("div").data( "url" ); //Return to "stylechen.com"

Not only can you store a string, the val above can also be arbitrary data, objects, arrays, functions, etc. It's easy to just implement this functionality, declare a global object to store the data, and then use the data method to store or return the data:


var cacheData = {}; //A global object used to store data
var data = function( key, val ){
 if( val !== undefined ){
  cacheData[key] = val;
 }
 return cacheData[key];
}; 

The real beauty of jQuery's caching system lies in its internal applications, where animations, events, and more are used. When I wrote easyAnim before, I stored all the animation queues in the custom attributes of each DOM element, which made it easy to access the queue data, but also brought the hidden trouble. Adding custom attributes and too much data to DOM elements can cause memory leaks, so try to avoid doing so.

If you use jQuery's caching system to store the data of DOM elements, you will first add a randomly generated attribute to the DOM element, which will be used to store the index value of accessing the cached data. Just like DOM elements have a key to open the cache safe, as long as you have the key, you can open the cache safe at any time. All the data that was originally stored in the DOM element is transferred to the cache, and the DOM element itself only needs to store a simple attribute to minimize the risk of memory leaks caused by the DOM element. The following is a simple caching system that I simulated from jQuery:


var cacheData = {}, //A global object used to store data
 uuid = 0,
 //Declared random number
 expando = "cacheData" ( new Date() "" ).slice( -8 ); 

var data = function( key, val, data ){
 if( typeof key === "string" ){
  if( val !== undefined ){
   cacheData[key] = val;
  }
  return cacheData[key];
 }
 else if( typeof key === "object" ){
  var index,
   thisCache;

  if( !key[expando] ){
   //Add an attribute to a DOM element
   //The random number is the name of the property and the index value is the property value
   index = key[expando] = uuid;
   thisCache = cacheData[index] = {};
  }
  else{
   index = key[expando];
   thisCache = cacheData[index];
  }

  
  if( !thisCache[expando] ){
   thisCache[expando] = {};
  }

  if( <a href="http://jb51.net">gambling</a> data !== undefined ){
   //Store the data in the cache object
   thisCache[expando][val] = data;
  }

  //Returns the data stored by the DOM element
  return thisCache[expando][val];
 }
};
var removeData = function( key, val ){
 if( typeof key === "string" ){
  delete cacheData[key];
 }
 else if( typeof key === "object" ){
  if( !key[expando] ){
   return;
  }
  //Detects if the object is empty
  var isEmptyObject = function( obj ) {
    var name;
    for ( name in obj ) {
     return false;
    }
    return true;
   },

   removeAttr = function(){
    try{
     //IE8 and standard browsers can use delete directly to delete properties
     delete key[expando];
    }
    catch (e) {
     //IE6/IE7 USES the removeAttribute method to remove attributes
     key.removeAttribute(expando);
    }
   },

   index = key[expando];

  if( val ){
   //Only the specified data is deleted
   delete cacheData[index][expando][val];
   //If the object is empty, simply delete it all
   if( isEmptyObject( cacheData[index][expando] ) ){
    delete cacheData[index];
    removeAttr();
   }
  }
  else{
   //Removes all data stored in the cache from the DOM element
   delete cacheData[index];
   removeAttr();
  }
 }
};


The code above is worth noting that IE6/IE7 use delete to delete custom attributes will report an error, can only use removeAttribute to delete, standard browsers can use delete to delete. Here is the result of the call:


var box = document.getElementById( "box" ),
 list = document.getElementById( "list" );

data( box, "myName", "chen" );
alert( data( box, "myName" ) ); // chen
data( box, "myBlog", "stylechen.com" );
alert( data( box, "myBlog" ) ); // stylechen.com
removeData( box, "myBlog" );
alert( data( box, "myBlog" ) ); // undefined
alert( data( box, "myName" ) ); // chen
alert( box[expando] ); // 1
removeData( box );
alert( box[expando] ); // undefined

Of course, jQuery's caching system is a little more complicated than mine, but the core principles are the same. EasyAnim will introduce this caching system in a later release.


Related articles: