What's the effect of data?
In our usual JS coding process, we often add a variety of custom attributes to the DOM element, so there is a disadvantage.
1, suppose we add a property to the DOM element, this attribute points to a JS object. Dom1.ele = Jsobj
2, when this JS object played a role, we have not used him. This is supposed to be the JS variable should be emptied, free memory. As we all know, if a JS object does not exist any external references, the interpreter will automatically remove it in memory, which is JavaScript relative to C + + and other manual memory management programs.
3, but this time the problem comes, because the DOM element refers to this JS object, although this JS object has no meaning of existence, but the interpreter will not delete him. If you want to delete it, we might want to set this property of the DOM element to null.
4, we have written so many code, where can each JS object is not referenced by DOM elements are remembered ah?
5, and, if the DOM element and JS object to each other circular reference, can not be deleted! This is the memory leak.
6. So, to avoid this happening, we should try to avoid referencing data (where the reference data can be said to be JavaScript objects) directly attached to the DOM object.
7, data is used to fix the above problems.
How does data handle the above issues?
First, the general idea of data implementation in jquery:
1, first we create a data cache pool, which is designed to store additional data that is attached to DOM objects or jquery objects.
2. When we want to append additional data to a DOM object or jquery object, our additional data is actually stored in this cache pool.
3. DOM objects or jquery objects generate an additional attribute that holds the ' number ' (location or index) of additional data in the cache pool.
4, when we access the DOM object or the additional data of the JQuery object, we actually get the number of the additional data, and then find the data of the corresponding number in the cache pool, and do the operation.
General ideas to finish, then to analyze the specific ideas:
In jquery, there is a data constructor that generates an instance whenever the constructor is run.
jquery automatically generates two data instances by default:
var datapriv = new Data () jquery Private, we try not to operate on this instance.
var datauser = new data () This is the service to the user, we use the Data () method is to operate on this instance.
All data instances have the following properties:
Expando: The value is a string type, and the value of the expando property of each data instance is different, to differentiate between instances of data, similar to the role of IDs, and the expando value is the extra attribute above.
UID: This is the number above, the initial 1, with the addition of different objects of data added, from the growth.
Cache: An Object {}, this is the buffer pool.
Here's an example:
$ (document.body). Data (' AAA ', ' value-aaa ')
Console.dir (Document.body)
|
The body object has a name of jquer210023 ... The extra attributes,
The name of this property is the value of the Datauser expando
The value of this property is the number.
Summary:data is actually a centralized management of the extra attributes of a JS object or DOM object. For additional data that does not produce a memory leak, we can also attach directly to the JS object or to the DOM object.
Well, after the relationship between the above, we will look at the source code:
],function (JQuery, Rnotwhite) {
Old WebKit does not have Object.preventextensions/freeze method,
return new empty object instead with no [[set]] accessor
Object.defineproperty (This.cache = {}, 0, {
Jquery.expando = "jquery" + (version + Math.random ()). Replace (/\d/g, "") expando is the only indication of a jquery
The format is: ' jquery\\d* ' is also ' jQuery ' + multiple digits. Why do you have to make such a mess here?
Because we might create multiple data objects, in order to ensure that the value of the expando property of each data object is not equal, so
This.expando = Jquery.expando + math.random ();
Data.uid = 1;//The properties of the data function, ' static properties '
data.accepts = Jquery.acceptdata;
We can accept data for non-element nodes in modern browsers,
But we should not, #8335.
Always return the key for a frozen object.
If owner has a corresponding cache object in the cache pool, the key of the mixed object (is a number) is returned.
If owner does not have a corresponding cache object in the cache pool, a cache object is created for it in the cache pool and the key of the cached object is returned
if (! Data.accepts (owner)) {
Check if the owner object already has a cache key
Check if the owner object has a cache in the cache pool
unlock = Owner[this.expando];//is a number that is used as the key to cache objects in the cache pool
Secure it in a non-enumerable, non-writable
Attach a property Owner[this.expando] = unlock to owner, and the attribute cannot be enumerated,
Descriptor[this.expando] = {Value:unlock};
Object.defineproperties (owner, descriptor);
Fallback to a less secure definition
Descriptor[this.expando] = unlock;
Jquery.extend (owner, descriptor);
Ensure that the cached object for owner already exists
if (!this.cache[unlock]) {
Set:function (owner, data, value) {
Set the cache object corresponding to owner
There May is a unlock assigned to this node,
If there is no entry to this "owner", create one inline
and set the unlock as though an owner entry had always existed
Unlock =this.key (owner),//Get owner of the corresponding cache object in the cache pool key (here's key, is the key value pairs of the meaning of the key)
Cache =this.cache[Unlock];//Gets the cached object for owner
Handle: [Owner, key, value] args
Implement overloads based on the number of incoming parameters and the type
if (Typeofdata = = "string") {
Handle: [Owner, {properties}] args
Fresh assignments by object are shallow copied
if (Jquery.isemptyobject (cache)) {
Jquery.extend (this.cache[unlock], data);
Otherwise, copy the properties one-by-one to the Cache object
cache[prop] = data[prop];
Returns the cached object
Get:function (owner, key) {
Gets the property value of the owner object named key
Owner: is an object (can be a jquery object or a DOM object) key: property name
Either a valid cache is found, or would be created.
New caches would be created and the unlock returned,
Allowing direct access to the newly created
Empty data object. A valid owner object must be provided.
Varcache =this.cache[this.key (owner)];//owner's Cached object
Returnkey = = undefined? cache:cache[key];//Returns the entire cache object if the key is not specified, and returns the value of the key property of the cached object if key is specified
Access:function (owner, key, value) {
1. No key was specified did not specify key
2. A string key was specified, but no value provided specified a strings-formatted key, but no value was specified
Take the "read" path and allow to determine
Which value to return, respectively either:
1. The entire cache object
2. The data stored the value of a key in the key cache object
if (key = = Undefined | | Key is not specified or has a string format specified, but value is not specified
(Key &&typeofkey = = "string") && value = = undefined)) {
Key not specified: Gets the entire cache object
Key in string format specified, but no value was specified: Gets the value of the key in the cached object
Stored =this.get (owner, key);
returnstored!== undefined?
Stored:this.get (owner, Jquery.camelcase (key));
[*]when The key is not a string, or both a key and value
are specified, set or extend (existing objects) with either:
When the key is not a string, or the key and value are specified, it is set or extended according to the situation
1. An object of properties
This.set (owner, key, value);
Since the "set" path can have two possible entry points
Return to the expected data based on which path is taken[*]
returnvalue!== undefined? Value:key;
Remove:function (owner, key) {
Clears the cached object for owner, or removes a key value pair from the cached object
Unlock =this.key (owner),
Cache =this.cache[unlock];
If key is not specified, the cached object is emptied
Support array or space separated string of keys
if (Jquery.isarray (key)) {
If ' name ' is ' an array of keys ...
When the data is initially created, via ("Key", "Val") signature,
The keys would be converted to CamelCase.
Since There is no way to tell _how_ a key was added, remove
Both plain key and CamelCase key. #12786
This is only penalize the array argument path.
Name = Key.concat (Key.map (jquery.camelcase));
Camel = jquery.camelcase (key);
Try the string as a key before any manipulation
If a key with the spaces exists, use it.
Otherwise, create an array by matching Non-whitespace
[Name]: (Name.match (rnotwhite) | | [] );
Hasdata:function (owner) {
Check if owner has cached objects in this cache pool
Return!jquery.isemptyobject (
this.cache[Owner[this.expando]] | | {}
Discard:function (owner) {
if (Owner[this.expando]) {
deletethis.cache[Owner[this.expando]];
|
A classmate might ask, "What if I want to do something with Datapriv?"
Please see source code:
Hasdata:function (elem) {
Returndatauser.hasdata (elem) | | Datapriv.hasdata (Elem);
Data:function (elem, name, data) {
Returndatauser.access (elem, name, data);
Removedata:function (Elem, name) {
Datauser.remove (elem, name);
Todo:now that all calls to _data and _removedata have been
With the direct calls to Datapriv methods, this can be deprecated.
_data:function (elem, name, data) {
Returndatapriv.access (elem, name, data);
_removedata:function (Elem, name) {
Datapriv.remove (elem, name);
|
Through the source, we can see:
The Jquery.data () Jquery.remove () all operate on the Datauser, and Jquery._data () Jquery._remove () all operate on Datapriv.
Understand the difference between jquery.data (Ele,name,data) and JQuery (). Data (Key,value).
Through the above source code, we can see that Jquery.data (Ele,name,data) is the ele element of additional data.
and jquery (). Data (Key,value) will append to all DOM objects in the jquery object separately
Look at the source code (part of the deletion):
</
Data:function (key, value) {
Attrs = Elem && elem.attributes;returnaccess (this,function (value) {
Camelkey = Jquery.camelcase (key);
As you can see from here, append data to each DOM element in the jquery object
A copy or reference of any of the attempt to store
Data that might ' ve been store with a camelcased key.
Vardata = Datauser.get (this, camelkey);
For HTML5 data-* attributes interop, we have to
Store property names and dashes in a camelcase form.
This might isn't apply to all properties...*
Datauser.set (this, camelkey, value);
// *... In the case of properties that might _actually_
Have dashes, we need to also store a copy of that
if (Key.indexof ("-")!==-1 && data!== undefined) {
Datauser.set (this, key, value);
},null, value, Arguments.length > 1,null,true);
Removedata:function (key) {
Returnthis.each (function () {
Datauser.remove (this, key);
|