Differences between jQuery object data Cache principle and jQuery. data method

Source: Internet
Author: User

There are many ways to use jQuery on the Internet. data (..) to implement data caching, but two users often use data ([key], [value]) and jQuery. data (element, [key], [value]) has almost no articles to clarify the differences between them, so I used it and shared it with you.

$ (""). Data ([key], [value]) and jQuery. data (element, [key], [value ])
These two functions are used to store data on elements, also known as data caching. They both return jQuery objects. At that time, when I used them separately, I was really shocked. The difference was big, I don't need to know. It's just a fright. Let's look at the example first, and then analyze it based on the source code.

Js Code:Copy codeThe Code is as follows: <div id = "test2" onclick = "test ()"> test2 </div>
<Div id = "abc3" onclick = "test ()"> test3 </div>
<Div id = "test" onclick = "test ()"> test </div>
<P id = "ttt"> aaaa </p>
<Script>
$ (Document). ready (function (){
$ ("# Test"). click (function (){
Alert ("JQUERY ");
Var e = $ ("div"); // defines two jquery objects.
Var w = $ ("div"); // e is not equal to w.
// Use data ([key], [value]) first.
$ (E). data ("a", "aaaa"); // save data with the same Key on e and w respectively,
$ (W). data ("a", "wwww"); // check whether it overwrites the previous one, although it is saved on different objects.
Alert ($ (e). data ("a"); // Have you guessed the answer? The output in is wwww; is it a bit unexpected?
Alert (e = w) // false
Alert ($ (w). data ("a"); // This is also wwww;
// Use jQuery. data (element, [key], [value]) to store data.
$. Data (e, "B", "cccc"); // save data with the same Key on e and w respectively,
$. Data (w, "B", "dddd"); // check whether it overwrites the previous one, although it is saved on different objects.
Alert ($. data (e, "B"); // you can guess the answer and output cccc
Alert ($. data (w, "B"); // This output dddd
});
});
</Script>

After reading the example above, I found that data ([key], [value]) and jQuery. data (element, [key], [value]) are fundamentally different, right? Is there any relationship between them. How does data ([key], [value]) overwrite the same value of the previous key?

JQuery. data (element, [key], [value]) does not overwrite any object bound to it. Is that true? Let's study their source code.

First look at jQuery. data (element, [key], [value]) source code.
Js Code:Copy codeThe Code is as follows: jQuery. extend ({
Cache :{},
// Please use with caution
Uuid: 0,
// Unique for each copy of jQuery on the page
// Non-digits removed to match rinlinejQuery
Expando: "jQuery" + (jQuery. fn. jquery + Math. random (). replace (/\ D/g ,""),
....
Data: function (elem, name, data, pvt/* Internal Use Only */){
// Whether data can be appended. If not, the system returns the result directly.
If (! JQuery. acceptData (elem )){
Return;
}
Var privateCache, thisCache, ret,
// JQuery. expando is a unique string generated when a jquery object is generated.
InternalKey = jQuery. expando,
GetByName = typeof name = "string ",
// You must differentiate between DOM elements and JS objects because the IE6-7 cannot recycle objects across DOM objects and reference attributes of JS objects
IsNode = elem. nodeType,
// If it is a DOM element, use the global jQuery. cache
// If it is a JS object, it is directly attached to the object
Cache = isNode? JQuery. cache: elem,
// Only defining an ID for JS objects if its cache already exists allows
// The code to export cut on the same path as a DOM node with no cache
Id = isNode? Elem [internalKey]: elem [internalKey] & internalKey,
IsEvents = name = "events ";
// Avoid unnecessary work. When trying to get data on an object without any data
// If the object does not have any data, it is returned directly.
If ((! Id |! Cache [id] | (! IsEvents &&! Pvt &&! Cache [id]. data) & getByName & data === undefined ){
Return;
}
// If the id does not exist,
If (! Id ){
// Only DOM nodes need a new unique ID for each element since their data
// Ends up in the global cache
If (isNode ){
// If it is a DOM element, it generates a unique ID on the element and uses jQuery. expando
// Save the attribute value as id on the elem element so that you can find the ID based on jQuery. expando later.
Elem [internalKey] = id = ++ jQuery. uuid;
} Else {
// JQuery. expando is directly used for JS objects. Why id is required since it is directly attached to objects?
// Avoid conflicts with other attributes!
Id = internalKey;
}
}
//// When we try to access whether a key contains a value, if the jQuery. cache [id] value does not exist,
// Initialize jQuery. cache [id] to an empty object {}
If (! Cache [id]) {
Cache [id] = {};
If (! IsNode ){
Cache [id]. toJSON = jQuery. noop;
}
}
// An object can be passed to jQuery. data instead of a key/value pair; this gets
// Shallow copied over onto the existing cache
// Data is the receiving object and function. It is a shortest copy.
If (typeof name = "object" | typeof name = "function "){
If (pvt ){
Cache [id] = jQuery. extend (cache [id], name );
} Else {
Cache [id]. data = jQuery. extend (cache [id]. data, name );
}
}
/Storage object, which stores the ing objects of all data
PrivateCache = thisCache = cache [id];
// JQuery data () is stored in a separate object inside the object's internal data
// Cache in order to avoid key collisions between internal data and user-defined
// Data.
// JQuery internal data has an independent object (thisCache. data = thisCache [internalKey])
// To avoid conflicts between internal data and user-defined data
If (! Pvt ){
// If the object storing private data does not exist, create {}
If (! ThisCache. data ){
ThisCache. data = {};
}
// Replace thisCache with a private data object
ThisCache = thisCache. data;
}
// If data is not undefined, the data parameter is passed in, and the data is stored on the name attribute.
If (data! = Undefined ){
// JQuery. camelCase (name) is used if the object/function is input and no conversion is performed,
// Only the input name is a string. Therefore, the key/value pair is saved;
ThisCache [jQuery. camelCase (name)] = data;
}
// After that, the following code processes data: function (elem, name) data is empty, and the returned data is obtained.
If (isEvents &&! ThisCache [name]) {
Return privateCache. events;
}
// If name is a string, data is returned.
// If not, the entire storage object is returned.
If (getByName ){
// First Try to find as-is property data
Ret = thisCache [name];
// Test for null | undefined property data
If (ret = null ){
// Try to find the camelCased property
Ret = thisCache [jQuery. camelCase (name)];
}
} Else {
Ret = thisCache;
}
Return ret;
},
............
});

See the figure

Look at jQuery. after the source code of data (element, [key], [value]), you can know that each element has its own {key: value} object, which stores data, therefore, even if the new object has the same key, it will not overwrite the value corresponding to the original object key, because the new object is saved in another {key: value} object.

Next we will analyze the data ([key], [value]) source code using each (callback). Before analyzing it, let's take a look at the each (callback) usage and source code.

Js Code:Copy codeThe Code is as follows: <div id = "test2" onclick = "test ()"> test2 </div>
<Div id = "abc3" onclick = "test ()"> test3 </div>
<Div id = "test" onclick = "test ()"> test </div>
<P id = "ttt"> aaaa </p>
<Script>
$ (Document). ready (function (){
$ ("# Test"). click (function (){
Alert ("JQUERY ");
Var I = 0;
$ ("# Abc3"). each (function (){
Alert (++ I); // only outputs 1, because only one <div id = "abc3">
});
Alert ("----");
Var j = 0;
$ ("Div"). each (function (){
Alert (++ j); // output values 1, 2, and 3 respectively. Because there are three <div>, the loop is repeated three times.
});
});
});
</Script>
The specific implementation of the each method is as follows:
JQuery. fn = jQuery. prototype = {
Each: function (callback, args ){
Return jQuery. each (this, callback, args );
}
}
We can see that it returns the global each method and uses its jQuery object as a parameter to it. The specific implementation of the global each method is as follows:
// Args is used as an internal Member for calling.
Each: function (object, callback, args ){
Var name, I = 0, length = object. length; // when the object is a jQuery object, the length is not empty.
If (args ){
If (length = undefined ){
For (name in object)
If (callback. apply (object [name], args) === false)
Break;
} Else
For (; I <length ;)
If (callback. apply (object [I ++], args) === false)
Break;
// The following is a client program call
} Else {
If (length = undefined ){
For (name in object)
If (callback. call (object [name], name, object [name]) === false)
Break;
} Else
// I indicates the index value, and value indicates the DOM element.
For (var value = object [0];
I <length & callback. call (value, I, value )! = False;
Value = object [++ I]) {}
}
Return object;
}

Now let's take a look at for (var value = object [0]; I <length & callback. call (value, I, value )! = False; value = object [++ I]) {}. In this Code, object [0] gets the first DOM element in the jQuery object, and uses the for loop,
Obtain each DOM element in the entire jQuery object and Use callback. call (value, I, value); direct this object of callback to the value object and pass two parameters. I indicates the index value and value indicates the DOM element; callback is similar to function (index, elem. So we get $ (""). each (function (index, elem ){});
Let's take a look at the source code of data ([key], [value ]).
Js Code:Copy codeThe Code is as follows: jQuery. fn. extend ({
Data: function (key, value ){
Var parts, part, attr, name, l,
Elem = this [0],
I = 0,
Data = null;
// Gets all values
If (key = undefined ){
... // Handle the case that no Key exists, which is not discussed here
Return data;
}
// Sets multiple values
If (typeof key = "object "){
Return this. each (function (){
JQuery. data (this, key );
});
}
Parts = key. split (".", 2 );
Parts [1] = parts [1]? "." + Parts [1]: "";
Part = parts [1] + "! ";
Return jQuery. access (this, function (value ){
If (value = undefined ){
... // If there is no value here, the returned value is requested, which is not discussed here
}
Parts [1] = value;
// If I use $ ("div "). data ("a", "aaa"). Before calling each, this indicates the $ ("div") returned object,
This. each (function () {// note that every matching element is used as the context to execute a function.
Var self = jQuery (this );
Self. triggerHandler ("setData" + part, parts );
// Here, data is stored on elements. In essence, data (element, [key], [value]) is delegated.
// See the previous analysis.
// In the following data (this, key, value), this indicates traversing each DOM element corresponding to the entire jQuery object.
// $ ("Div") corresponds to an <div> array in the page.
JQuery. data (this, key, value) <span style = "background-color: # ffcc00;" >;// this sentence is executed cyclically multiple times, that is, save the data </span>.
// Here is the core sentence. But it should be clear that it is in each (functipn.
Self. triggerHandler ("changeData" + part, parts );
});
}, Null, value, arguments. length> 1, null, false );
},
// Remove the stored data from the element. The specific implementation is as follows:
RemoveData: function (key ){
Return this. each (function (){
JQuery. removeData (this, key );
});
}
});

If you don't know much about the source code of data ([key], [value]), let's use an example to simulate it.
Js Code:Copy codeThe Code is as follows: <div id = "test2" onclick = "test ()"> test2 </div>
<Div id = "abc3" onclick = "test ()"> test3 </div>
<Div id = "test" onclick = "test ()"> test </div>
<P id = "ttt"> aaaa </p>
<Script>
$ (Document). ready (function (){
$ ("# Test"). click (function (){
Alert ("JQUERY ");
Var I = 0;
$ ("# Abc3"). each (function (){
Alert (++ I); // only outputs 1, because only one <div id = "abc3">
});
Alert ("----");
Var j = 1;
$ ("Div"). each (function () {// execute this function with every matching element as the context
$. Data (this, "a", "wwww"); // here this refers to $ ("div "),
// Traverse each matching element to save a key/value for each object {}.
Alert (j ++); // output 1, 2, and 3 respectively because there are three <div> Elements
});
Alert ($ ("# test"). data ("a"); // return wwww,
// Isn't it amazing? I didn't save it on it. Why does it have a value? It is obvious that it is checking whether there is a div node,
// There must be a value, because the above gives the loop stored on the Dom node of the div.
Alert ($ ("# test") ===$ ("div"); // false proves that the two newly created objects are not the same.
Alert ($ ("div"). data ("a"); // return wwww,
// The same is true here because "a" = "wwww" is saved on the div node.
});
});
</Script>

Data ([key], [value]) and jQuery. data (element, [key], [value]) can be understood. If you still have a half understanding, read it again and patiently understand it. Actually, it is quite different on the surface. However, there is a link in nature. After understanding the principles, you can use them with peace of mind. JQuery. data (element, [key], [value]) only binds data to the Parameter element Node. Data ([key], [value])
For example, $ ("div"). data ("a", "aaaa") binds data to each element that matches the div node.
Additional instructions, the analysis of the use of the source code of the jquery-1.7.2.js. : Http://demo.jb51.net/jslib/jquery/jquery-1.7.2.min.js

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.