$.data()、$().data

两个方法很相似,但是有区别,简单说一下:

$.data():jq的静态方法,也就是jQuery.data()直接调用

$().data():实例方法,先有实例,才能调用这个方法,例如:$("#id").data("name","zhangsan")

区别:

通过例子说下:

var div1 = $("#d1");
var div2 = $("#d1");
$.data(div1, "name", "zhangsan");
$.data(div2, "name", "lisi");
document.write($.data(div1).name);//zhangsan
document.write($.data(div2).name);//zhangsan

div1.data("name", "zhangsan");
div2.data("name", "lisi");
document.write(div1.data("name"));//lisi
document.write(div2.data("name"));//lisi

顺便说一下他们定义的来源,$.extend(),$.fn.extend();这篇文章讲的不错,大家可以看一下http://caibaojian.com/jquery-extend-and-jquery-fn-extend.html

$.extend():增加全局函数、对象,相当于给jQuery这个类增加了静态方法

$.fn.extend():这个是对jQuery.prototype进得扩展(原来 jQuery.fn = jQuery.prototype),就是为jQuery类添加“成员函数”

ok,进入正题,先来看静态方法:$.data();

举几个例子:

$.data($("#id"),"name","zhangsan");

$.data({},"name","zhangsan");

$.data({},{"name",function(){}});

等等jQuery.extend({

    data: function( elem, name, data ) {
		return internalData( elem, name, data );
	}
    ...
}
//内部方法
function internalData( elem, name, data, pvt /* Internal Use Only */ ){     //检测这个elem是否可接受数据
	if ( !jQuery.acceptData( elem ) ) {
		return;
	}
    
	var thisCache, ret,          //随机号,jquery加载的时候初始化它,expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" )
		internalKey = jQuery.expando,          //name是string类型为true
		getByName = typeof name === "string",

		// We have to handle DOM nodes and JS objects differently because IE6-7
		// can‘t GC object references properly across the DOM-JS boundary         // 必须区分处理DOM元素和JS对象,因为IE6-7不能垃圾回收对象跨DOM对象和JS对象进行的引用属性(这个目前还不太懂)		isNode = elem.nodeType,

		// Only DOM nodes need the global jQuery cache; JS object data is
		// attached directly to the object so GC can occur automatically         //如果是dom节点,则cache取jq全局的cache,否则取elem本身,这个也是静态和实例data方法的一个重要区别
		cache = isNode ? jQuery.cache : elem,
        
		// Only defining an ID for JS objects if its cache already exists allows
		// the code to shortcut on the same path as a DOM node with no cache          //如果已经存在cache,则直接取,如果不存在则undefined
		id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;

	// Avoid doing any more work than we need to when trying to get data on an
	// object that has no data at all     //对象没有任何数据,直接返回
	if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {
		return;
	}
     //id不存在
	if ( !id ) {
		// Only DOM nodes need a new unique ID for each element since their data
		// ends up in the global cache          //如果是dom节点,则添加internalKey/guid这个键值对到elem上,方便以后调用
		if ( isNode ) {
			elem[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++;
		} else {//非dom节点,比如自己创建的对象{}
			id = internalKey;
		}
	}
     //cache[id]不存在则添加一个空对象
	if ( !cache[ id ] ) {
		cache[ id ] = {};

		// Avoids exposing jQuery metadata on plain JS objects when the object
		// is serialized using JSON.stringify          //废掉cache[id]的toJSON方法,防止这个对象进行序列化通过toJSON方法,从而暴露jQuery的元数据(还不太理解)
		if ( !isNode ) {
			cache[ id ].toJSON = jQuery.noop;
		}
	}

	// An object can be passed to jQuery.data instead of a key/value pair; this gets
	// shallow copied over onto the existing cache       //如果是对象或者函数,则浅克隆它到cache[id]的data属性
	if ( typeof name === "object" || typeof name === "function" ) {
		if ( pvt ) {
			cache[ id ] = jQuery.extend( cache[ id ], name );
		} else {
			cache[ id ].data = jQuery.extend( cache[ id ].data, name );
		}
	}

	thisCache = cache[ id ];

	// jQuery data() is stored in a separate object inside the object‘s internal data
	// cache in order to avoid key collisions between internal data and user-defined
	// data.     //不是内部元素的话定义赋值cache相关属性
	if ( !pvt ) {          //cache[id].data不存在则创建		if ( !thisCache.data ) {
			thisCache.data = {};
		}
          //单独取出data对象
		thisCache = thisCache.data;
	}
     //如果此处data有定义,则把name/data赋值到cache.data的上面,即cache.data={name:data}
	if ( data !== undefined ) {          //camelCase这个函数是驼峰函数,进行一些大小写的,如a-and-b-》aAndB
		thisCache[ jQuery.camelCase( name ) ] = data;
	}

	// Check for both converted-to-camel and non-converted data property names
	// If a data property was specified        如果name是String类型的,则取对应的data值(“zhangsan”),否则返回cache中的data对象({name:funciton(){}})
	if ( getByName ) {

		// First Try to find as-is property data
		ret = thisCache[ name ];

		// Test for null|undefined property data
		if ( ret == null ) {

			// Try to find the camelCased property
			ret = thisCache[ jQuery.camelCase( name ) ];
		}
	} else {
		ret = thisCache;
	}

	return ret;
}

  

时间: 2025-01-08 00:13:09