jquery 3.0 was officially released on June 9, and 3.0 is also known as the next generation of jquery. This version began in October 14 with a beta release (2016/1/14,) and a candidate version (2016/05/20). It's not easy to walk all the way.
First, data analysis
The Data in JQuery 3.0 is used internally and is defined as a "class". Altogether it created two objects, Datapriv and Datauser. Data has 1 object attributes (expando) and class attributes (UID), and there are 6 methods, as follows
Read the following separately
1, Data.uid
This is a number from 1 starting with the increase.
2, expando
The combination of Jquery.expando and UID, which is used as the key for elements such as DOM elements, is unique. Jquery.expando is generated as follows
Jquery.expando = "JQuery" + (version + Math.random ()). Replace (/\d/g, "")
That is, ' jQuery ' + (version number + random number), and then remove the non-numeric, such as
Remove the non-number into
jQuery30009423638425146147 "
JQuery 3.0 Internal variables Datapriv and Datauser generated expando are as follows
jquery 024727210109188635 1
jquery 300 024727210109188635 2
The third part is random number, each refresh will change, the other part of the same.
3, Cache
Cache method will tie an object to owner as storage, owner must meet Acceptdata, cache will take This.expando as Clue key.
There are two kinds of owner, one is the DOM element (NodeType is 1 and 9), the other is the normal JS object. such as text nodes (nodetype=3), annotation nodes (nodetype=8) are not added.
The definition of Acceptdata is as follows
var acceptdata = function (owner) {
//accepts only:
//-Node
// -Node.element_node
// -NODE.D Ocument_node
//-Object
// -any/
* jshint-w018/return
Owner.nodetype = = 1 | | owner.nodety PE = = 9 | | ! (+owner.nodetype);
};
The acceptdata is used in a total of 3 places in 3.0, respectively
The cache method for the Data class, which is not available to programmers for proprietary methods. $.cleandata the method, emptying all cached data associated with the element. is a public method, but is rarely used. This method is used in empty, HTML, ReplaceWith, and remove methods. $ (). Trigger method, the active distribution of events, for the public method.
If it is a DOM element, then use the point operator directly to assign value, if it is normal JS object then use ES5 Object.defineproperty method, this is also JQuery 3.0 will use the new API embodiment.
If it is a node unlikely to being stringify-ed or looped over
//use plain assignment
if (owner.nodetype) {
owner[This.expando] = value;
Otherwise secure it non-enumerable property
//Configurable must is true to allow the property to being
//DE leted when the data
is removed} else {
object.defineproperty (owner, This.expando, {
value:value,
Configurable:true
});
Converted to the following code
elem[' jQuery3000247272101091886351 '] = dataobj;
var person = {name: ' John ', age:30};
Object.defineproperty (person, ' jQuery3000247272101091886351 ', {
value:dataobj,
configurable:true
} );
The cache method is this, the incoming owner, only the first time set, return value (a null object), and then return directly after the value.
Source
Cache:function (owner) {
//Check If the owner object already has a cache
var value = owner[This.expando];
//if not, create one
if (!value) {
value = {};
We can accept data for non-element nodes at modern browsers,
//But we should not, #8335.
Always return a empty object.
if (Acceptdata (owner) {
//If It is a node unlikely to being stringify-ed or looped over
//use plain Assignme NT
if (owner.nodetype) {
owner[This.expando] = value;
Otherwise secure it non-enumerable property
//Configurable must is true to allow the
Deleted when the data
is removed} else {
object.defineproperty (owner, This.expando, {
value:value,
Configurable:true
});
}} return value;
},
4, set
The above cache method creates an empty object with expando as key for owner, and all subsequent methods are expanded around this empty object, which is called the cached object, and all subsequent data is added to it. Set is a building block for this object, set each time to retrieve the cache, and then add new attributes and data. If data is a string, it is added as a key, and if it is an object, it is added by traversing it. Just be aware that the horizontal line connector will be turned into hump format, which is also for compatibility with H5 Data-xxx.
Source
Set:function (owner, data, value) {
var prop,
cache = This.cache (owner);
Handle: [Owner, key, value] args
//Always use CamelCase key (gh-2257)
if (typeof data = = "string")
{ cache[jquery.camelcase (data)] = value;
Handle: [Owner, {properties}] args
} else {
//Copy The properties One-by-one to the cache object
for (Prop in data) {
cache[jquery.camelcase (prop)] = data[prop];
}
return cache;
},
5, get
Get is very simple, the key is from the cache to retrieve the value of the key, nothing to retrieve the entire cache.
Source
Get:function (owner, key) {return
key = = undefined?
This.cache (owner):
//Always use CamelCase key (gh-2257)
owner[This.expando] && owner[This.expando] [Jquery.camelcase (Key)];
6, Access
This method is instantly getter, and also setter, that's all.
Getter condition
The key is undefined, when the entire cachekey is a string and value is undefined, which is the values of the specified key
Setter conditions
Owner, key, value three parameters are passed
Source
Access:function (owner, key, value) {//In cases where either:////1. No key was specified//2. A string key is specified, but no value provided////Take the "read" path and allow the Get method to determine/ /which value to return, respectively either:////1. The entire cache object//2.
The data stored at the key//if (key = = Undefined | | (key && typeof key = = "string" && value = = undefined))
{return This.get (owner, key); }//When the key isn't a string, or both a key and value//are specified, set or extend (existing objects) with EIT Her:////1. An object of properties//2.
A key and Value//This.set (owner, key, value);
Since the "set" path can have two possible entry points//return the expected data based on which path is taken[*] return value!== undefined?
Value:key; },
7. Remove
Empty the cache object above the binding element (owner), still need to get cache by This.expando first, if pass key then delete the value of the specified key (key itself is also deleted).
Of course, the JQuery API maintains the convenience that the key can be an array, so that multiple keys can be deleted in batches. If key does not pass the entire cache will be deleted, here distinguishes the DOM and ordinary JS objects, DOM objects using undefined assignment, JS object is using Delete.
Source
Remove:function (owner, key) {var I, cache = owner[This.expando];
if (cache = = undefined) {return;
} if (key!== undefined) {//Support array or space separated string of keys if (Jquery.isarray (key)) {
The If key is an array of keys ...//We always set CamelCase keys, so remove.
Key = Key.map (jquery.camelcase);
else {key = Jquery.camelcase (key);
If a key with the spaces exists, use it.
Otherwise, create an array by matching non-whitespace key = key in cache? [Key]: (Key.match (rnotwhite) | |
[] );
} i = Key.length;
while (i--) {delete cache[key[i]]; }//Remove the expando if there ' s no more data if (key = = Undefined | | jquery.isemptyobject (CACHE)) {// Support:chrome <=35-45//Webkit & Blink Performance suffers when deleting properties//From DOM nodes , so set to undefined instead//https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) if (Owner.nodetype) {owner[This.expand
O] = undefined;
else {delete owner[This.expando]; }
}
},
8, HasData
Used to determine if there is cached data on the owner, return TRUE or false.
Source
Hasdata:function (owner) {
var cache = owner[This.expando];
Return cache!== undefined &&!jquery.isemptyobject (cache);
}
Second, the use of data within the jquery
All of the above data-reading methods, mentioned above, also mention that the data class was used inside JQuery, creating its two objects altogether: Datapriv and Datauser.
These two objects have a clear division of labor in 3.0.0, and Datapriv can guess the combination of "data" and "private" two words. That is, Datapriv is private to service the JQuery internal method, and Datauser is used to serve the methods that are exposed to the user.
Here's a look at which modules the two objects are distributed in.
Full version Click Expand to view
Datapriv
public
$.hasdata
$.cleandata
clonecopyevent
queue
$ (). Queue
$ (). _queuehooks
$ (). Promise
Animation
$ (). Animate $ ().
Stop
$ (). Finish
showhide
event
$.event.add
$.event.remove
$.event.dispatch
$.event.trigger
other
setglobaleval
Dommanip
Defaultprefilter
$ (). Toggleclass
datauser
public
$.hasdata
$.cleandata
Clonecopyevent
Cache
$.data
$.removedata
$ (). Data
$ (). Removedata
Other
dataattr
The above can be seen, in addition to "public", Datapriv used in the JQuery queue, animation, events and other modules, Datauser used in the data cache and dataattr modules.
"Public" means that the three methods are used for Datapriv and Datauser.
$.hasdata (Elem)
Used to determine if the associated data cache is bound on the Elem, returns True and false, and returns false only on Datapriv and Datauser.
Source
Hasdata:function (elem) {return
datauser.hasdata (elem) | | datapriv.hasdata (elem);
},
$.cleandata (Elems)
Empty all data caches bound by Elem, and of course need to empty both Datapriv and Datauser.
Note: Although this method is publicly exposed to $, there is no introduction to the method on the official website API. Improper use of the other can have serious consequences, such as after binding the event (. On), calling the method, and the bound event will all expire. Because all the data in the Datapriv will be emptied.
Clonecopyevent (SRC, dest)
This is an internal method that $.clone will use to it. When cloning an element, the data bound to node is cloned, in addition to the node nodes being cloned. Like what
var cloneNode = $.clone (elem);
Cloning the Elem to CloneNode, this time Elem added on the event CloneNode will also have.
Iii. comparison of 1.x.x and 2.x.x
The versions of the JQuery 1.x and 2.x series differ greatly from the implementation of the data cache module. You can compare my 11 years of this article
1. Cached data structure
1.x (until 1.11.2) cache is stored on the Jquery.cache, 2.x (including 3.x) uses an internal class Data cache, which mainly uses two objects Datapriv and Datauser. It is obvious that 2.x do better, all of its cached data are private, there will be no risk of being wrongly written, and 1.x Jquery.cache is open, if it is mistakenly written (for example, a classmate to add a cache object to the $) is disastrous.
2. Jquery._data
This underline is known to be private (the formula) and is only used internally in 1.x and is not provided to the developer. In the 1.11.2 example, this method is used by event modules, queue modules, animation modules, Setglobaleval, Clonecopyevent, Fixclonenodeissues, Dommanip, Showhide, Defaultprefilter, Toggleclass use. 3.x use Datapriv and Datauser instead, we can compare and see.
(2/3). x is significantly better than 1.x, Datapriv and Datauser are truly proprietary (packaged better, more secure) than 1.x-agreed private jquery._data. Although 3.0.0 is also conservative compatible with the Jquery._data, I believe that after a later version will be removed.
3. Refactoring
The 1.x is centered around the $._data to assist in implementing other APIs, (2/3). x is implemented as center of Datapriv/datauser. (2/3). x reconstructs the code and extracts the Data class to make it clearer.
The above is a small set to introduce the jquery 3.0 in the full description of the data, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!