The principle of cache caching for jquery object and the Jquery.data of its method _jquery

Source: Internet
Author: User
Tags extend shallow copy unique id uuid
There's a lot of online teaching you how to use Jquery.data (..) To implement the data cache, but there are two of users who often use data ([Key],[value]) and Jquery.data (Element,[key],[value]) few articles to clarify the difference between them, so I used, research to share.

$ (""). The difference between data ([Key],[value]) and Jquery.data (Element,[key],[value])
These two functions are used to store the data on the elements is usually said that the data cache, are returned to the jquery object, I was in the use of them when the two really scared me, the difference can be big, really do not know, a use of fright. Look at the example first, and then according to the source code analysis.

JS Code:
Copy Code code 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.
//First use the data ([Key],[value]) usage.
$ (E). Data ("A", "AAAA"), and/or on the E and W to save the same key,
$ (w). Data ("A", "wwww");/See if it will overwrite the front, although it is saved on a different object.
Alert ($ (e). Data ("a");/Do you guess the answer, the output is wwww; Is it a bit of an accident?
Alert (e===w)//false
Alert ($ (w). Data ("a"));//This is also wwww;
//Use Jquery.data (Element,[key],[value]) to store the data.
$.data (E, "B", "CCCC");//Save key-like data on E and W respectively,
$.data (W, "B", "dddd");/See if it will overwrite the front, although it is saved on a different object.
Alert ($.data (E, "B"));/Should you be able to guess the answer, output CCCC
Alert ($.data (W, "B"));//This output dddd
});
});
</script>

See the above example is not found in the data ([Key],[value]) and Jquery.data (Element,[key],[value]) Two is not the same, right? Is there any relationship between them? How does data ([Key],[value]) overwrite the same value as the previous key?

Jquery.data (Element,[key],[value]) does not cause overlays as long as they are bound to different objects. Is that right? Let's take a look at their source code.

First look at the Jquery.data (Element,[key],[value]) source code.
JS Code:
Copy Code code as follows:

Jquery.extend ({
Cache: {},
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 the data can be attached or not directly returned to the
if (!jquery.acceptdata (Elem)) {
Return
}
var privatecache, Thiscache, ret,
Jquery.expando This is a unique string that is generated when the jquery object is generated.
Internalkey = Jquery.expando,
Getbyname = typeof Name = = "String",
You must differentiate between DOM elements and JS objects, because ie6-7 cannot garbage reclaim reference properties of objects across Dom objects and JS objects
Isnode = Elem.nodetype,
If it is a DOM element, the global Jquery.cache is used
If it is a JS object, it is attached directly to the object
Cache = Isnode? JQuery.cache:elem,
Only defining a ID for JS objects if it cache already exists allows
The code to shortcut on the same path as a DOM node with no cache
id = isnode? elem[Internalkey]: elem[Internalkey] && Internalkey,
isevents = name = = "Events";
Avoid doing more work, and when trying to get data on an object that doesn't have any data,
Object does not have any data, it returns directly
if (!id | |!cache[id] | | (!isevents &&!pvt &&!cache[id].data)) && getbyname && data = = undefined) {
Return
}
If the ID does not exist, it generates a
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 produces a unique ID on the element and a Jquery.expando
Save the attribute value as an ID on the Elem element so that you can later find the ID based on the Jquery.expando.
elem[Internalkey] = id = ++jquery.uuid;
} else {
JS object is directly using Jquery.expando, since it is directly attached to the object, why should ID?
Avoid conflicts with other properties!
id = internalkey;
}
}
When we try to access a key that contains a value, if there is no jquery.cache[id value,
Initialize Jquery.cache[id] value is an empty object {}
if (!cache[id]) {
cache[id] = {};
if (!isnode) {
cache[id].tojson = jquery.noop;
}
}
An object can is 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, shallow 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 holds all the data mapped objects
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 exists in a separate object (thiscache.data==thiscache[Internalkey])
, in order to avoid internal data and user-defined data conflicts
if (!PVT) {
The object that holds private data does not exist, a {} is created
if (!thiscache.data) {
Thiscache.data = {};
}
Replacing Thiscache with private data objects
Thiscache = Thiscache.data;
}
If data is not undefined, which means that the data parameter is passed in, then the data to the Name property is stored
if (data!== undefined) {
The jquery.camelcase (name) function is if the incoming is object/function and does not convert,
Only the passed-in name is a string that is converted. So the final preservation is key/value pair;
thiscache[jquery.camelcase (name) = data;
}
Since then, the following code handles the Data:function (elem, name) data as null and returns the value of data.
if (isevents &&!thiscache[name]) {
return privatecache.events;
}
If name is a string, the data is returned
If not, the entire storage object is returned
if (getbyname) {
The 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;
},
............
});

Please look at the picture

Look at the Jquery.data (Element,[key],[value]) source code, you can know that each element will have its own {Key:value} object holds the data, So if the new object has the same key, it will not overwrite the value of the original object key, because the new object is saved in another {Key:value} object.

The next step is to analyze the data ([Key],[value]) source code using each (callback), and look at each (callback) usage and source code before parsing it.

JS Code:
Copy Code code 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);//output only 1 because there is only one <div id= "ABC3" >
});
Alert ("----");
var j=0;
$ ("div"). each (function () {
alert (++j);//output 1,2,3 separately because there are three <div> so cycle three times
});
});
});
</script>
Now let's look at the specific implementation of each method as follows:
Jquery.fn = Jquery.prototype = {
Each:function (callback, args) {
Return Jquery.each (this, callback, args);
}
}
You can see that it returns the global each method, and its jquery object as a parameter to it, the overall implementation of each method is as follows:
Args as an internal member of the call to use the
Each:function (object, callback, args) {
var name, i = 0, length = object.length; When object is a jquery object, 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 what the client program calls
} else {
if (length = = undefined) {
For (name in object)
if (Callback.call (object[name, name, object[name]) = = False)
Break
} else
I represents the index value, value represents the DOM element
for (var value = object[0];
I < length && Callback.call (value, I, value)!== false;
Value = Object[++i]) {}
}
return object;
}

Now let's focus on the for (var value = object[0]; I < length && Callback.call (value, I, value)!== false; value = object[+ +i] {} This code, where Object[0] gets the first DOM element in the jquery object, through the For Loop,
Gets the corresponding each DOM element traversing the entire jquery object, through Callback.call (Value,i,value); The This object of the callback is pointed to the value object, and two arguments are passed, I represents the index value, and value represents the DOM element, where callback is a method similar to the function (index, elem) {}. So we get $ (""). each (function (index, elem) {});
Let's look at the source code of data ([Key],[value])
JS Code:
Copy Code code 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) {
.../handling no key, this is not what we're talking about.
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) {
。。。 Here is no value when it is requested to return the value of the case, which is not what we discussed
}
PARTS[1] = value;
If I use $ ("div"). Data ("A", "AAA"), the following call each before this refers to $ ("div") This returns the object,
This.each (function () {//note, here is the execution of a function with each matching element as context
var self = jQuery (this);
Self.triggerhandler ("SetData" + part, parts);
This is where the data is stored on the element, and it is essentially commissioned by data (Element,[key],[value]).
Look at the previous analysis.
This in the following data (this, key, value) refers to each of the corresponding DOM elements that traverse the entire jquery object
$ ("div") it corresponds to a <div> array on the page.
Jquery.data (this, key, value) <span style= "Background-color: #ffcc00;" >;//This quote will be executed multiple times, that is, save the data </span>.
Here is the core of a sentence. But you have to see it clearly. It is in each (FUNCTIPN () {}).
Self.triggerhandler ("Changedata" + part, parts);
});
}, NULL, value, Arguments.length > 1, NULL, FALSE);
},
Removes the stored data on the element. Specifically implemented as follows:
Removedata:function (key) {
Return This.each (function () {
Jquery.removedata (this, key);
});
}
});

If you don't know the source code for data ([Key],[value]) Well, I'll use an example to simulate it.
JS Code:
Copy Code code 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);//output only 1 because there is only one <div id= "ABC3" >
});
Alert ("----");
var j=1;
$ ("div"). each (function () {//) executes the functions as a context for each matching element
$.data (This, "a", "wwww");//This here means $ ("div"),
Each of the matching elements is traversed to each of them, and each object {} is saved with a key/value
Alert (j + +), Output 1, 2, 3, respectively, because there are three <div> elements
});
Alert ($ ("#test"). Data ("a");//Return WWWW,
is not very surprised, I did not save on it, ah, how there is value, it is obviously it is to check this div node there is no,
There must be a value, because the loop is saved to the DOM node of the Div.
Alert ($ ("#test") ===$ ("div");//false prove that the two new objects are not the same.
Alert ($ ("div"). Data ("a"));/return wwww,
It's the same here. Because the div node holds "a" = "wwww" so that a key value is right.
});
});
</script>

Now the data ([Key],[value]) and Jquery.data (Element,[key],[value) have understood it, if it is still half understand, and then look back again, patiently understand. In fact, the surface is very different. But in essence there is a connection, now understand the principle can be used at ease. Jquery.data (Element,[key],[value]) binds data only to the parameter element node. Data ([Key],[value])
such as $ ("div"). Data ("A", "AAAA") it is to bind data to every element that matches a div node.
In addition to the instructions, the article is used to analyze the source code of the jquery-1.7.2.js. Download Address: 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.