五、数据缓存Data2——jQuery.data( elem, name, data )、jQuery._data(elem, name, data)
实际代码:
// 代码行:4004——4158 function Data() { // 设定唯一标识 this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; Data.prototype = { // 建立一个cache cache: function( owner ) { // Check if the owner object already has a cache // 检查所有者对象是否已经拥有缓存 var value = owner[ this.expando ]; // If not, create one // 如果没有value,则创建一个 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. // 我们可以在现代浏览器中接受非元素节点的数据,但是我们不应该这么做,总是返回一个空对象。 if ( acceptData( owner ) ) { // If it is a node unlikely to be stringify-ed or looped over // use plain assignment //如果它是一个不太可能被字符串化或循环的节点,使用简单的赋值 // 判断owner是一个合格者后 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 //否则,将其保护在一个不可枚举的属性中 //可配置的必须为true才能允许属性为true //删除数据时删除 } else { Object.defineProperty( owner, this.expando, { value: value, configurable: true } ); } } } return value; }, // set()用于dom设置key和value 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[ camelCase( data ) ] = value; // Handle: [ owner, { properties } ] args // 处理data为这种情况:[ owner, { properties } ] } else { // Copy the properties one-by-one to the cache object // 将属性逐个复制到缓存对象 for ( prop in data ) { cache[ camelCase( prop ) ] = data[ prop ]; } } return cache; }, get: function( owner, key ) { return key === undefined ? this.cache( owner ) : // Always use camelCase key (gh-2257) owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; }, // 用来访问,将get、set结合到一起,并对underfined判断 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 "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 // //在下列任何一种情况下:1.没有指定密钥。2.指定了字符串键,但没有提供值。选择“read”路径并允许get方法确定,分别返回哪个值:1.整个缓存对象 2.存储在键上的数据 // 如果key是undefined或key是字符串、data是undefined说明实在读取数据 if ( key === undefined || ( ( key && typeof key === "string" ) && 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 // //当键不是字符串,或者键和值都不是时。指定、设置或扩展(现有对象)时,1.属性的对象。2.键和值 this.set( owner, key, value ); // Since the "set" path can have two possible entry points // return the expected data based on which path was taken[*] // 因为“set”路径可以有两个可能的入口点 // 返回所选择路径的期望数据[*] return value !== undefined ? value : key; }, // 用于移除cache 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 // 支持删除数组格式的key if ( Array.isArray( key ) ) { // If key is an array of keys... // We always set camelCase keys, so remove that. key = key.map( camelCase ); } else { // 为了保持一致,强行的构造了一个数组 key = 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 // cache为空的时候,删除整个缓存 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.expando ] = undefined; } else { delete owner[ this.expando ]; } } }, hasData: function( owner ) { var cache = owner[ this.expando ]; return cache !== undefined && !jQuery.isEmptyObject( cache ); } }; var dataPriv = new Data(); var dataUser = new Data(); jQuery.extend( { // 代码行:4228——4230 // 方法jQuery.data()用于为DOM元素或JavaScript对象设置任意类型的数据,或返回指定名称的数据,或返回关联的数据缓存对象。通过调用dataUser.access(elem, name, data) data: function( elem, name, data ) { // 参数elem:表示与数据关联的DOM元素。 // 参数name:表示要设置或读取的数据名,或者时含有键值对的对象。 // 参数data:表示要设置的数据值,可以时任意类型。 return dataUser.access( elem, name, data ); }, // 代码行:4238——4240 // TODO: Now that all calls to _data and _removeData have been replaced // with direct calls to dataPriv methods, these can be deprecated. // 方法jQuery._data(elem, name, data )用于为DOM元素或JavaScript对象设置或读取内部数据,通过调用方法dataPriv.access(elem, name, data)实现 // 在jQuery内部,方法jQuery._data(elem, name, data)用于为队列模块、动画模块、样式操作模块、事件系统提供基础功能,负责设置或读取这些模块运行时的内部数据。 _data: function( elem, name, data ) { return dataPriv.access( elem, name, data ); } } );

浙公网安备 33010602011771号