jQuery.data方法

先看用法:

看jq源码

<span style="font-size:14px;">var data_user

function Data() {
	Object.defineProperty( this.cache = {}, 0, {
		 get: function() {
			 return {};
		}
	});
	this.expando = jQuery.expando + Math.random();
}

Data.uid = 1;

Data.accepts = function( owner ) {
	return owner.nodeType ?
 		owner.nodeType === 1 || owner.nodeType === 9 : true;
};

Data.prototype = {
	key: function( owner ) {
		if ( !Data.accepts( owner ) ) {
			return 0;
		}

		var descriptor = {},
			unlock = owner[ this.expando ];

		if ( !unlock ) {
			unlock = Data.uid++;
			try {
				 descriptor[ this.expando ] = { value: unlock };
				Object.defineProperties( owner, descriptor );
			  } catch ( e ) {
				descriptor[ this.expando ] = unlock;
				 jQuery.extend( owner, descriptor );
			}
		}

		if ( !this.cache[ unlock ] ) {
 			this.cache[ unlock ] = {};
		}

		 return unlock;
	},
	set: function( owner, data, value ) {
		var prop,
			unlock = this.key( owner ),
			cache = this.cache[ unlock ];

		if ( typeof data === "string" ) {
			cache[ data ] = value;

		} else {
			if ( jQuery.isEmptyObject( cache ) ) {
				jQuery.extend( this.cache[ unlock ], data );
			} else {
				 for ( prop in data ) {
					 cache[ prop ] = data[ prop ];
 				}
 			}
 		}
 		return cache;
	},
	get: function( owner, key ) {
		var cache = this.cache[ this.key( owner ) ];

		 return key === undefined ?
 			cache : cache[ key ];
 	},
	access: function( owner, key, value ) {
		var stored;
		if ( key === undefined ||
				 ((key && typeof key === "string") && value === undefined) ) {

 			stored = this.get( owner, key );

 			return stored !== undefined ?
 				stored : this.get( owner, jQuery.camelCase(key) );
		}

		this.set( owner, key, value );

		return value !== undefined ? value : key;
 	},
	remove: function( owner, key ) {
 		var i, name, camel,
 			unlock = this.key( owner ),
			cache = this.cache[ unlock ];

 		if ( key === undefined ) {
			this.cache[ unlock ] = {};

		} else {
			if ( jQuery.isArray( key ) ) {
				name = key.concat( key.map( jQuery.camelCase ) );
			} else {
				camel = jQuery.camelCase( key );
				if ( key in cache ) {
					name = [ key, camel ];
				} else {
					// If a key with the spaces exists, use it.
					// Otherwise, create an array by matching non-whitespace
					name = camel;
					name = name in cache ?
						[ name ] : ( name.match( core_rnotwhite ) || [] );
				}
			}

			i = name.length;
			while ( i-- ) {
				delete cache[ name[ i ] ];
			}
		}
	},
	hasData: function( owner ) {
		return !jQuery.isEmptyObject(
			this.cache[ owner[ this.expando ] ] || {}
		);
	},
	discard: function( owner ) {
		if ( owner[ this.expando ] ) {
			delete this.cache[ owner[ this.expando ] ];
		}
	}
};

data_user = new Data();


jQuery.extend({
	acceptData: Data.accepts,

	hasData: function( elem ) {
		return data_user.hasData( elem );
	},

	data: function( elem, name, data ) {
		return data_user.access( elem, name, data );
	},

	removeData: function( elem, name ) {
		data_user.remove( elem, name );
	}
});</span>


1、

Data构造函数,defineProperty的作用:定义Data.cache = { 0:function(){return {}} },这里的k值和方法是不能修改,this.expando,取一个随机数

function Data() {
    Object.defineProperty( this.cache = {}, 0, {
        get: function() {
            return {};
        }
    });

    this.expando = jQuery.expando + Math.random();
}


2、

$.data()方法,实际调用的是Data的实例方法

data_user = new Data();
jQuery.extend({
    acceptData: Data.accepts,

    hasData: function( elem ) {
        return data_user.hasData( elem ) || data_priv.hasData( elem );
    },

    data: function( elem, name, data ) {
        return data_user.access( elem, name, data );
    },

    removeData: function( elem, name ) {
        data_user.remove( elem, name );
    }
});


3

这里做的判断意思是:当传入的对象有nodeType,并且等于1(元素)或9(document),或者是其他对象,就返回真

Data.accepts = function( owner ) {
    return owner.nodeType ?
        owner.nodeType === 1 || owner.nodeType === 9 : true;
};


4、this.expando是随机数,放到对象身上。unlock是cache的k值

对应关系:{this.expando: unlock},cache = {unlock: value}


key: function( owner ) {

    //这里进行筛选,只有通过的对象才能继续,没有通过的对象都返回0,因为0不能修改,不能通过的对象所有取值都是{}。

    if ( !Data.accepts( owner ) ) {
        return 0;
    }
    //descriptor后面会赋值为:{this.expando: unlock}

    var descriptor = {},
        unlock = owner[ this.expando ];

    //如果unlock不存在,就赋值Data.uid++,并且给传入对象(假如为obj)赋值:obj[this.expando] = unlock

    if ( !unlock ) {
        unlock = Data.uid++;
        try {
            descriptor[ this.expando ] = { value: unlock };
            Object.defineProperties( owner, descriptor );
        } catch ( e ) {
            descriptor[ this.expando ] = unlock;
            jQuery.extend( owner, descriptor );
        }
    }

    //缓存,和obj的unlock对应起来

    if ( !this.cache[ unlock ] ) {
        this.cache[ unlock ] = {};
    }

    return unlock;
}

5、set为赋值操作

set: function( owner, data, value ) {
    var prop,

        //获取对象对应缓存的k值,并且通过k值取出缓存空间

        unlock = this.key( owner ),
        cache = this.cache[ unlock ];
    //这里为for in循环赋值
    if ( typeof data === "string" ) {
        cache[ data ] = value;
    } else {
        if ( jQuery.isEmptyObject( cache ) ) {
            jQuery.extend( this.cache[ unlock ], data );
        } else {
            for ( prop in data ) {
                cache[ prop ] = data[ prop ];
            }
        }
    }
    return cache;
}

6、通过传入对象,要取的K值,获取对应的值。如果传入的key没有,则返回所有缓存的值

get: function( owner, key ) {
    var cache = this.cache[ this.key( owner ) ];

    return key === undefined ?
        cache : cache[ key ];
}

7、

access方法,通过传入的参数值,分别调用赋值/取值方法


8、

remove方法:删除缓存中对应的K值

hasData方法:判断对象身上是否有缓存(对应的cache中是否还存在有值)

discard:删除对象身上的随机数值,作用彻底清空和缓存的绑定关系


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值