Deep understanding of how Jquery.data () is implemented _jquery

Source: Internet
Author: User
Tags garbage collection uuid

The role of Jquery.data () is to append (and get) data to a normal object or DOM Element.

The following is a three-part analysis of how it is implemented:

1. Append data to object with name and value; Pass in three parameters, the first parameter is the object that needs additional data, the second parameter is the name of the data, and the third parameter is the value of the data. Of course, if you just get a value, you can also pass the third argument.

2. Append data to object with another object; two parameters are passed in, the first parameter is the data object that needs to be appended (we call it "obj"), the second parameter is an object (which we call "another"), and the key-value pairs contained in "another" are copied to "obj" Data cache (which we call "cache").

3. Append data for DOM element; Dom element is also an object, but IE6 and IE7 have problems with garbage collection of objects that are directly attached to DOM element; So we store this data in the global cache (we call it "GLOBALCAC He "," Globalcache "contains the" cache "of multiple DOM element, and adds an attribute on the DOM element that holds the UID corresponding to" cache ".

Append data to object with name and value

When attaching data to a normal object using Jquery.data (), the essence is to attach a "cache" to the object and use a special property name.

The cache that holds the data is also an object, and the data we append to "obj" actually becomes the property of "cache". and "Cache" is an attribute of "obj", in JQuery 1.6, the name of this attribute is "JQUERY16" plus a random number ("jQuery16018518865841457738" as mentioned below).

We can use the following code to test the function of Jquery.data ():

<script type= "Text/javascript" src= "Jqueryjs" ></script> 
<script> 
obj = {}; 
$data (obj, ' name ', ' value '); 
Documentwrite ("$data (obj, ' name ') =" + $data (obj, ' name ') + ' <br/> '); 
 
for (var key in obj) { 
 documentwrite ("obj" + key + ' name = ' + Obj[key]name '); 
} 

Display results as:

$.data (obj, ' name ') = value 

In this code, we first attach an attribute on "obj" (named "Name", "value"), and then get the attached data by $.data (obj, ' name '). To gain an insight into the implementation mechanism, we used a loop to get the attributes of "obj", actually removing the "cache" object appended to "obj".

As you can see, jquery.data () actually attaches "obj" to an object named "jQuery16018518865841457738" (the name is random), that is, on the cache. The attribute attached to an object in Jquery.data () is actually a property of this "cache".

We can use the following code to implement similar functions:

$ = function () { 
 var expando = "JQuery" + ("6" + mathrandom ()) Replace (/\d/g, "); 
 
 function GetData (cache, name) {return 
 cache[name]; 
 } 
 
 function SetData (cache, name, value) { 
 Cache[name] = value; 
 } 
 
 function GetCache (obj) { 
 Obj[expando] = Obj[expando] | | {}; 
 return Obj[expando]; 
 } 
 
 return { 
 data:function (obj, name, value) { 
  var cache = GetCache (obj); 
 
  if (value = = = undefined) {return 
  getData (cache, name); 
  } else { 
  setData (cache, name, value); 
  } 
 } 
 } 
}(); 

The first line of code in a function defines "expando", or "jQuery1.6" Add a random number (0.xxxx) and remove the portion of the central-African digits; This format will be used elsewhere in jquery, not discussed here; just know that this is a special name and can be used to identify different pages (like "expando" in different iframe). will be different).

Next, we define the function getData () that gets the data, that is, get a property from the cache; it is actually returning cache[name].

The SetData () function is then used to set the property of cache, which is actually the value of setting Cache[name].

Then GetCache () gets the cache on "obj", that is Obj[expando], and initializes if Obj[expando is empty.

Finally, the data method is disclosed, based on the incoming "obj", gets the "cache" attached to "obj", the GetData () method is invoked when two parameters are passed in, and the SetData () method is invoked when three arguments are passed in.

Append data to an object with another object

In addition to assigning value by providing name and value, we can also pass directly to another object ("another") as an argument. In this case, the property name and property values of "another" are treated as multiple key-value pairs, and the "name" and "value" extracted from them are copied to the target object's cache.

The functional test code is as follows:

<script type= "Text/javascript" src= "Jqueryjs" ></script> 
<script> 
obj = {}; 
$data (obj, {name1: ' value1 ', name2: ' value2 '}); 
 
Documentwrite ("$data (obj, ' name1 ') =" + $data (obj, ' name1 ') + ' <br/> '); 
Documentwrite ("$data (obj, ' name2 ') =" + $data (obj, ' name2 ') + ' <br/> '); 
 
for (var key in obj) { 
 documentwrite ("obj" + key + ' name1 = ' + obj[key]name1 + ' <br/> '); 
 Documentwrite ("obj" + key + ' name2 = ' + obj[key]name2); 
} 
</script> 

The results appear as follows:

$.data (obj, ' name1 ') = value1 
$.data (obj, ' name2 ') = value2 obj.jQuery1600233050178663064.name1 
= value1 

In the test code above, we first pass a "another" object with two key pairs, and then fetch the additional data with $.data (obj, ' name1 ') and $.data (obj, ' name2 '), and in order to understand the mechanism, we iterate through the The "obj" method takes out the hidden "cache" object and obtains the value of the "Name1" property and the "Name2" property of the Cache object.

As you can see, jquery.data () actually attaches an object named "obj.jquery1600233050178663064" to "obj" on "cache". Key-value pairs passed in Jquery.data () are copied to the cache.

We can use the following code to implement similar functions:

$ = function () { 
 //other codes 
 
 function Setdatawithobject (cache, another) {for 
 (var name in another) { 
  C Ache[name] = Another[name]; 
 } 
 
 Other codes return 
 
 { 
 data:function (obj, name, value) { 
  var cache = GetCache (obj); 
 
  if (name instanceof Object) { 
  setdatawithobject (cache, name) 
  } else if (value = = undefined) {return 
  GETDA TA (cache, name); 
  else { 
  setData (cache, name, value);}}} 
  

This code is modified on the basis of the previous code. First, the internal function setdatawithobject () is added, and the implementation of this function is to traverse the properties of "another" and copy it to "cache".

Then, in the Open Data function, first determine the name of the second argument passed in, and call the Setdatawithobject () method if the argument is an instance of type Object.

Append data to DOM Element

Because DOM element is also an object, the previous approach can also assign values to DOM element, but given the problem of garbage collection in IE6, IE7 (which cannot efficiently reclaim the additional object references on DOM element), jquery uses a common object that does not Additional data in the same way.

The test code is as follows:

<script type= "Text/javascript" src= "Datajs" ></script> 
<script> 
windowonload = function () { 
 div = Documentgetelementbyid (' div_test '); 
 $data (Div, ' name ', ' value '); 
 Documentwrite ($data (Div, ' name ')); 
} 

The results appear as follows:

 
 

In the test code, you first get a DOM element (or, of course, a jQuery selector) by using the document.getElementById method, then attach a property to the DOM element, and then from the DOM element The attached property is removed and output.

Because we do not attach objects directly to the DOM element, given the problem of IE6, IE7 garbage Collection on object references on DOM element, we use global cache and append a UID to the DOM element.

The implementation method is as follows:

$ = function () { 
 var expando = "JQuery" + ("6" + mathrandom ()) Replace (/\d/g, "); 
 var globalcache = {}; 
 var uuid = 0; 
 
 Other Codes 
 
 function GetCache (obj) { 
 if (objnodetype) { 
  var id = obj[expando] = Obj[expando] | | ++uuid;
   
    globalcache[id] = Globalcache[id] | | {}; 
  return globalcache[id]; 
 } else { 
  Obj[expando] = Obj[expando] | | {}; 
  return Obj[expando]; 
 } 
 
 Other codes 

   

This code adds globalcache and UUID compared to the previous code, and modifies the GetCache () method.

The Globalcache object is used to store "cache" attached to the DOM Element and can be considered a "cache" container. The UUID represents the unique identifier for "cache", which is unique and self growing. The UUID or is stored in the "expando" attribute of the DOM Element.

The GetCache () function adds a judgment that "obj" has the "NodeType" attribute, which is considered to be a DOM Element, in which case the ID appended to "obj", that is Obj[expando], is first removed; if Obj[expan Do is not defined, it is initialized with ++uuid, and after the ID is removed, the corresponding "cache", or Globalcache[id], is found in the Globalcache and returned.

So far, the implementation of the Jquery.data () function is finished; But here's another question to consider: "Globalcache" Storage for Shbudu, and "cache" directly attached to ordinary objects? I think this should be a way to optimize performance, after all, less than a reference level, access speed should be slightly faster. There are so many things that are deliberately optimized in jQuery, and there are special treatments for a lot of other people who can be treated uniformly. But this, to a certain extent, has also created barriers to reading the source code. This, of course, is the programming philosophy of the author (and other contributors to the code), and there is no comment here.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.