search
HomeWeb Front-endJS TutorialMethods of data operation in jQuery and the definition of jQuery

This article introduces to you the methods of data operation in jQuery and the definition of jQuery. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

There are two methods for data operations in jQuery

$().data()

$.data(elem);

The internal implementation is inseparable from custom classesData

Internal classesData

##Data is defined in src/data/Data.js, and the expando attribute is added to the instance when building, as a unique Identification

function Data() {
    this.expando = jQuery.expando + Data.uid++;
}
Added multiple methods on the prototype

Data.prototype = {
    cache: function(){
        ...
    },
    set: function(){
        ...
    },
    get: function(){
        ...
    },
    access: function(){
        ...
    },
    remove: function(){
        ...
    },
    hasData: function(){
        ...
    }
}
Inside jq, use the cache method to obtain cached data. Pass in a parameter owner, indicating the object to obtain cached data. Determine whether there is an expando attribute on the owner. If not, it indicates whether the owner is called for the first time and needs to initialize the cache data object. Determine the type of node. If it is an element node, document node or object, you can set cache data. If it is an element node or document node, use object literals directly for assignment. The attribute name is expando and the value is an empty object. If it is an object, use

Object.defineProperty to define data for it. The property name is also expando and initialized to {}. At the same time, the property descriptor can be changed and cannot be enumerated.

Data.prototype.cache
    cache: function( owner ) {

        // Check if the owner object already has a cache
        // 获取在owner的缓存值
        var value = owner[ this.expando ];

        // If not, create one
        if ( !value ) {
            value = {};

            // We can accept data for non-element nodes in modern browsers,
            // but we should not, see #8335.
            // Always return an empty object.
            // 判断owener类型 是否能在其上调用data
            // 在元素节点或body或对象上可以设置data
            // 其他节点不设置缓存数据
            if ( acceptData( owner ) ) {

                // If it is a node unlikely to be stringify-ed or looped over
                // use plain assignment
                // 此处为owner添加属性 key为Data对象的expando值 建立owner和Data对象之间的连接
                // owner是元素节点或body
                if ( owner.nodeType ) {
                    owner[ this.expando ] = value;

                // Otherwise secure it in a non-enumerable property
                // configurable must be true to allow the property to be
                // deleted when data is removed
                // owner是对象
                // 为owner添加expando属性 初始化为{},同时属性描述符可以更改,不可枚举
                } else {
                    Object.defineProperty( owner, this.expando, {
                        value: value,
                        configurable: true
                    } );
                }
            }
        }

        return value;
    }

Use

set to update the cache object, which is divided into data(key,value) or data(obj) In both calling cases, the key name must be saved in camel case when saving.

Data.prototype.set
    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;
    }

Use

get to obtain the cache object. When calling, there is data(key) and data(). If the key is not specified, the entire cache object is returned directly, otherwise cache[key] is returned. Key names must also be converted to camel case.

Data.prototype.get
    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 ) ];
    }

distinguishes the calling method, internally calling

set or get

Distinguish by the number and type of parameters:

  • When the key is empty, get the entire cache object

  • The key type is

    string and value===undefined corresponds to obtaining the specified value

  • Other calls are

    set, in setInternal differentiation

##Data.prototype.access

<pre class="brush:php;toolbar:false">    access: function( owner, key, value ) {         // In cases where either:         //         //   1. No key was specified         //   2. A string key was specified, but no value provided         //         // Take the &quot;read&quot; 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 &amp;&amp; typeof key === &quot;string&quot; ) &amp;&amp; value === undefined ) ) {             return this.get( owner, key );         }         // When the key is not a string, or both a key and value         // are specified, set or extend (existing objects) with either:         //         //   1. An object of properties         //   2. A key and value         //         this.set( owner, key, value );         // Since the &quot;set&quot; path can have two possible entry points         // return the expected data based on which path was taken[*]         return value !== undefined ? value : key;     }</pre>Use

remove

to delete cached object attributes , when calling, you can pass in a string representing the key name to be deleted, or pass in a string array that holds multiple key names. Key names must also be converted to camel case. If no parameters are passed in or out, the cached data object on the owner will be deleted directly.

Data.prototype.remove

<pre class="brush:php;toolbar:false">    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 ( Array.isArray( key ) ) {                 // If key is an array of keys...                 // We always set camelCase keys, so remove that.                 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( rnothtmlwhite ) || [] );             }             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 </pre>Determine whether there is cached data on the owner.

Data.prototype.hasData

<pre class="brush:php;toolbar:false">    hasData: function( owner ) {         var cache = owner[ this.expando ];         return cache !== undefined &amp;&amp; !jQuery.isEmptyObject( cache );     }</pre>

Definition of jQuery method

Inner class after definition

data

After that, expand in /src/data.js. Added hasData, data, removeData, _data, _removeData and other methods to jQuery, in jQuery.fn Added data and removeData methods. The methods expanded in jQuery are all encapsulations of the Data method. When calling

$.data()

, there is no pairing of set and The get operation is distinguished, and set and get are distinguished internally in Data.prototype.access. In the source code below, dataUser and dataPriv are Data instances, which respectively cache data and indicate whether the jq object adds the element's data attribute to dataUser<pre class="brush:php;toolbar:false">// $.data jQuery.extend( {     hasData: function( elem ) {         return dataUser.hasData( elem ) || dataPriv.hasData( elem );     },     data: function( elem, name, data ) {         return dataUser.access( elem, name, data );     },     removeData: function( elem, name ) {         dataUser.remove( elem, name );     },     // TODO: Now that all calls to _data and _removeData have been replaced     // with direct calls to dataPriv methods, these can be deprecated.     _data: function( elem, name, data ) {         return dataPriv.access( elem, name, data );     },     _removeData: function( elem, name ) {         dataPriv.remove( elem, name );     } } );</pre>The only methods extended on

jQuery.fn

are data and removeData. In data, first handle the two calling situations $().data() and $().data({k:v}) . If it is the first case, the cached data object on this[0] is returned. If it is the first time to call $().data(), at the same time The data attribute on the element will also be added to dataUser, and dataPriv will be updated. If it is the calling method of $().data({k:v}), the jq object is traversed and the cached data is updated for each node. Other calling methods such as $().data(k) and $().data(k,v) call access for processing. The access here is not Data.prototype.access.

removeData

Traverse the jq object and delete the cached data on each node. <pre class="brush:php;toolbar:false">// $().data jQuery.fn.extend( {     data: function( key, value ) {         var i, name, data,             elem = this[ 0 ], // elem为dom对象             attrs = elem &amp;&amp; elem.attributes; // 节点上的属性         // Gets all values         // $().data()         if ( key === undefined ) {             if ( this.length ) {                 data = dataUser.get( elem );                 // elem是元素节点,且dataPriv中无hasDataAttrs时执行这个代码块里的代码                 // dataPriv上的hasDataAttrs表示elem是否有data-xxx属性                 // 初始化dataPriv后花括号内的代码不再执行,即以下的if内的代码只执行一次                 if ( elem.nodeType === 1 &amp;&amp; !dataPriv.get( elem, &quot;hasDataAttrs&quot; ) ) {                     i = attrs.length;                     while ( i-- ) {                         // Support: IE 11 only                         // The attrs elements can be null (#14894)                         // 将elem的data-*-*属性以*-*转为驼峰命名方式的值为键                         // 在dataAttr函数内保存到dataUser中                         // 所以用$().data可以获取元素的data-*属性 但修改后dom上的属性却不变化                         if ( attrs[ i ] ) {                             name = attrs[ i ].name;                             // name为data-xxx                             if ( name.indexOf( &quot;data-&quot; ) === 0 ) {                                 // name为xxx                                 name = jQuery.camelCase( name.slice( 5 ) );                                 dataAttr( elem, name, data[ name ] );                             }                         }                     }                     // 同时将dataPriv的hasDataAttrs属性设置为真,表示已经将元素属性节点上的data属性保存到缓存对象中                     dataPriv.set( elem, &quot;hasDataAttrs&quot;, true );                 }             }             return data;         }                  // Sets multiple values         //  $().data(obj) 此处遍历this,即遍历jq对象上所有的节点,并在其设置值         if ( typeof key === &quot;object&quot; ) {             return this.each( function() {                 dataUser.set( this, key );             } );         }         // 除了$().data()和$().data({k:v})的其他情况         return access( this, function( value ) {             var data;             // The calling jQuery object (element matches) is not empty             // (and therefore has an element appears at this[ 0 ]) and the             // `value` parameter was not undefined. An empty jQuery object             // will result in `undefined` for elem = this[ 0 ] which will             // throw an exception if an attempt to read a data cache is made.             // value undefined说明是获取操作             // 调用$().data(k)             if ( elem &amp;&amp; value === undefined ) {                 // Attempt to get data from the cache                 // The key will always be camelCased in Data                 // 从dataUser中获取 非undefined时返回                 data = dataUser.get( elem, key );                 if ( data !== undefined ) {                     return data;                 }                 // Attempt to &quot;discover&quot; the data in                 // HTML5 custom data-* attrs                 // dataUser中不存在key,调用dataAttr查找元素的data-*属性                 // 如果存在属性,更新dataUser并返回其值                 data = dataAttr( elem, key );                 if ( data !== undefined ) {                     return data;                 }                 // We tried really hard, but the data doesn't exist.                 return;             }             // Set the data...             // jq对象长度 &gt;= 1, 调用如$().data(k,v) 遍历jq对象,为每个节点设置缓存数据             this.each( function() {                 // We always store the camelCased key                 dataUser.set( this, key, value );             } );         }, null, value, arguments.length &gt; 1, null, true );     },     // 遍历jq对象,删除各个元素上的缓存数据     removeData: function( key ) {         return this.each( function() {             dataUser.remove( this, key );         } );     } } );</pre>Among them,

getData

is used to perform type conversion on the data attribute on the element, and dataAttr is used to obtain the data attribute saved on the element node and update it at the same time. dataUser. It should be noted that when calling in the $().data(k, v) method, if the attribute cannot be found on the cached data, dataAttr will be called to find the attribute on the element. . <pre class="brush:php;toolbar:false">// 属性值是string 进行类型转换 function getData( data ) {     if ( data === &quot;true&quot; ) {         return true;     }     if ( data === &quot;false&quot; ) {         return false;     }     if ( data === &quot;null&quot; ) {         return null;     }     // Only convert to a number if it doesn't change the string     // data转化成number再转成string后仍严格等于data     if ( data === +data + &quot;&quot; ) {         return +data;     }     if ( rbrace.test( data ) ) {         return JSON.parse( data );     }     return data; } // 获取元素的dataset中的属性,并保存到dataUser中 function dataAttr( elem, key, data ) {     var name;     // If nothing was found internally, try to fetch any     // data from the HTML5 data-* attribute     // 此处获取dataset里的值     if ( data === undefined &amp;&amp; elem.nodeType === 1 ) {         name = &quot;data-&quot; + key.replace( rmultiDash, &quot;-$&amp;&quot; ).toLowerCase(); // 此处将驼峰命名方式的key转化为data-*-*         data = elem.getAttribute( name );         if ( typeof data === &quot;string&quot; ) {             try {                 data = getData( data );             } catch ( e ) {}             // Make sure we set the data so it isn't changed later             // 将元素的data-*属性保存到dataUser中             dataUser.set( elem, key, data );         } else {             data = undefined;         }     }     return data; }</pre> Recommended related articles:

Introduction to two methods of Angular form validation

How to use JavaScript functions? Introduction to the properties and methods of JavaScript functions

The above is the detailed content of Methods of data operation in jQuery and the definition of jQuery. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
JavaScript Comments: A Guide to Using // and /* */JavaScript Comments: A Guide to Using // and /* */May 13, 2025 pm 03:49 PM

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

Python vs. JavaScript: A Comparative Analysis for DevelopersPython vs. JavaScript: A Comparative Analysis for DevelopersMay 09, 2025 am 12:22 AM

The main difference between Python and JavaScript is the type system and application scenarios. 1. Python uses dynamic types, suitable for scientific computing and data analysis. 2. JavaScript adopts weak types and is widely used in front-end and full-stack development. The two have their own advantages in asynchronous programming and performance optimization, and should be decided according to project requirements when choosing.

Python vs. JavaScript: Choosing the Right Tool for the JobPython vs. JavaScript: Choosing the Right Tool for the JobMay 08, 2025 am 12:10 AM

Whether to choose Python or JavaScript depends on the project type: 1) Choose Python for data science and automation tasks; 2) Choose JavaScript for front-end and full-stack development. Python is favored for its powerful library in data processing and automation, while JavaScript is indispensable for its advantages in web interaction and full-stack development.

Python and JavaScript: Understanding the Strengths of EachPython and JavaScript: Understanding the Strengths of EachMay 06, 2025 am 12:15 AM

Python and JavaScript each have their own advantages, and the choice depends on project needs and personal preferences. 1. Python is easy to learn, with concise syntax, suitable for data science and back-end development, but has a slow execution speed. 2. JavaScript is everywhere in front-end development and has strong asynchronous programming capabilities. Node.js makes it suitable for full-stack development, but the syntax may be complex and error-prone.

JavaScript's Core: Is It Built on C or C  ?JavaScript's Core: Is It Built on C or C ?May 05, 2025 am 12:07 AM

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript Applications: From Front-End to Back-EndJavaScript Applications: From Front-End to Back-EndMay 04, 2025 am 12:12 AM

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Python vs. JavaScript: Which Language Should You Learn?Python vs. JavaScript: Which Language Should You Learn?May 03, 2025 am 12:10 AM

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.

JavaScript Frameworks: Powering Modern Web DevelopmentJavaScript Frameworks: Powering Modern Web DevelopmentMay 02, 2025 am 12:04 AM

The power of the JavaScript framework lies in simplifying development, improving user experience and application performance. When choosing a framework, consider: 1. Project size and complexity, 2. Team experience, 3. Ecosystem and community support.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools