The role of Jquery.data () is to append (and retrieve) data to a normal object or DOM Element.
The following is a three-part analysis of how it is implemented:
1. Append data to the object with name and value, i.e. 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 the value, you can not pass in the third argument.
2. Append the data to the object with another object, i.e. pass in two parameters, the first parameter is the data object that needs to be appended (we call "obj"), the second parameter is also an object (what we call "another"); the key-value pairs contained in "another" will be copied to "obj" Data cache (which we call "cache").
3. Append data to DOM element; Dom element is also an object, but IE6, IE7 has problems with garbage collection of objects directly attached to the DOM element, so we store this data in the global cache (What we call "GLOBALCAC He ")," Globalcache "contains the" cache "of multiple DOM element and adds a property on the DOM element to hold the corresponding UID of" cache ".
attaching data to an object with name and value
When attaching data to a normal object using Jquery.data (), it is essentially attaching a "cache" to the object and using a special property name.
The "cache" that holds the data is also an object, and the data that we append to "obj" actually becomes the "cache" property. and "Cache" is also a property of "obj", in JQuery 1.6, the name of this property is "JQUERY16" plus a random number (as mentioned below "jQuery16018518865841457738").
We can use the following code to test the functionality of Jquery.data ():
- <script type="Text/javascript" src="Jquery.js"></script>
- <script>
- obj = {};
- $.data (obj, ' name ', ' value ');
- document.write ("$.data (obj, ' name ') =" + $.data (obj, ' name ') + '<br /> ');
- for (var key in obj) {
- document.write ("obj." + key + '. Name = ' + Obj[key].name);
- }
- </Script>
The results shown are:
- $.data (obj, ' name ') = value
- Obj.jQuery16018518865841457738.name = Value
In this code, we first append an attribute to "obj" (named "Name", "value") and then get the appended data through $.data (obj, ' name '). In order to gain an insight into the implementation mechanism, we have used a loop to get the properties of "obj", in effect removing the "cache" object attached to "obj".
As you can see, jquery.data () actually attaches "obj" to an object named "jQuery16018518865841457738" (the name is random), that is, "cache". The property attached to an object in Jquery.data () is actually a property of the "cache".
We can implement a similar function with the following code:
- $ = function () {
- var expando = "JQuery" + ("1.6" + math.random ()). 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 function defines "expando", or "jQuery1.6" Add a random number (0.xxxx) and remove the parts of the non-digital part; This format will be used elsewhere in jquery, not explored here; just know that this is a special name and can be used to identify different pages (such as "expando" in different iframe) will be different).
Next, you define the function GetData () that gets the data, which is to get a property from "cache", which in effect returns Cache[name].
The SetData () function is then used to set the "cache" property, which is actually the value of setting Cache[name].
This is followed by GetCache (), which gets the "cache" on "obj", i.e. Obj[expando], and if Obj[expando] is empty, it is initialized.
Finally, the data method is disclosed, the "cache" appended to "obj" is obtained based on the "obj", and the GetData () method is called when the two parameters are passed, and the SetData () method is called when the three parameters are passed.
attaching data to an object with another object
In addition to assigning values in the form of a name and value, we can also pass directly to another object ("another") as a parameter. In this case, the property names and property values of "another" are treated as multiple key-value pairs, and the "name" and "value" from which they are extracted are copied to the cache of the target object.
The functional test code is as follows:
- <script type="Text/javascript" src="Jquery.js"></script>
- <script>
- obj = {};
- $.data (obj, {name1: ' value1 ', name2: ' value2 '});
- document.write ("$.data (obj, ' name1 ') =" + $.data (obj, ' name1 ') + '<br /> ');
- document.write ("$.data (obj, ' name2 ') =" + $.data (obj, ' name2 ') + '<br /> ');
- for (var key in obj) {
- document.write ("obj." + key + '. name1 = ' + obj[key].name1 + '<br /> ');
- document.write ("obj." + key + '. name2 = ' + obj[key].name2);
- }
- </Script>
The results appear as follows:
- $.data (obj, ' name1 ') = value1
- $.data (obj, ' name2 ') = value2
- obj.jQuery1600233050178663064.name1 = value1
- obj.jQuery1600233050178663064.name2 = value2
In the above test code, we first pass in a "another" object with two key-value pairs, and then use $.data (obj, ' name1 ') and $.data (obj, ' name2 ') to get the additional data, and again, for a closer look at the mechanism, we traverse 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", which is "cache". Key-value pairs passed in Jquery.data () are copied to the "cache".
We can implement a similar function with the following code:
- $ = function () {
- //Other codes ...
- function Setdatawithobject (cache, another) {
- For (var name in another) {
- Cache[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 GetData (cache, name);
- } Else {
- SetData (cache, name, value);
- }
- }
- }
- }();
This code is modified on the basis of the previous code. The inner function setdatawithobject () is added first, 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 parameter passed in, and if this argument is an instance of type Object, call the Setdatawithobject () method.
attaching data to DOM Element
Because the DOM element is also an object, the previous method can also assign a value to the DOM element, but considering the garbage collection problem in IE6, IE7 (which does not effectively reclaim the attached object reference on the DOM element), jquery uses a common object that has no Append data in the same way.
The test code is as follows:
- <div id="div_test" />
- <script type="Text/javascript" src="Data.js"></script>
- <script>
- Window.onload = function () {
- div = document.getElementById (' div_test ');
- $.data (Div, ' name ', ' value ');
- document.write ($.data (Div, ' name '));
- }
- </Script>
The results appear as follows:
- Value
In the test code, a DOM element is obtained first through the document.getElementById method (or, of course, with the jQuery selector), and then a property is appended to the DOM element and then from the DOM element The additional attributes are removed and output.
Because there is a problem with IE6, IE7 garbage collection on the object reference on DOM element, we do not attach the object directly to the DOM element, but instead use the global cache and append a UID to the DOM element.
Here's how it's implemented:
- $ = function () {
- var expando = "JQuery" + ("1.6" + math.random ()). Replace (/\d/g, " );
- var globalcache = {};
- var uuid = 0;
- //Other codes ...
- function GetCache (obj) {
- if (obj.nodetype) {
- 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 to the previous code, and modifies the GetCache () method.
The Globalcache object is used to hold the "cache" attached to the DOM Element and can be considered a "cache" container. The UUID represents the unique identifier for "cache" and 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 a "nodeType" attribute, which is considered to be a DOM Element, in which case the ID appended to "obj", or Obj[expando], is first removed; if Obj[expan Do] is undefined, it is initialized with ++uuid, and after the ID is removed, the corresponding "cache", or Globalcache[id], is found in the Globalcache and returned.
At this point, the implementation of the Jquery.data () function is finished, but here's a question to consider: "Globalcache" Storage for Shbudu, and "cache" directly to a normal object? I think this should be a way of performance optimization, after all, less a reference to the level, the access speed should be slightly faster. This is a much-sought-after optimization in JQuery, with special handling in many of the others that could have been handled uniformly. But this to a certain extent, also caused the reading source of obstacles. This is, of course, the programming philosophy of the author (and other code contributors), and there is no comment.
Jquery.data () is the implementation of ($.data ())