数据缓存:
构造函数Data():
var obj = {'name':'hello'};
Object.defineProperty(obj,0,{
get: function() {
return {};
}
});
console.log(obj[0]);//Object {}
console.log(obj['name']);//hello
obj[0] = 123;
obj[name]='world';
console.log(obj[0]);//Object {}
console.log(obj[name]);//world
上述Object.defineProperty()函数的作用是给obj对象添加了一个属性0,并且该属性只能读取,不能修改,但是其他属性可以修改,如:name属性的值就发生了变化。
构造函数Data()源码:
function Data() {
Object.defineProperty( this.cache = {}, 0, {
get: function() {
return {};
}
});
this.expando = jQuery.expando + Math.random();
}
Data.uid = 1;
Data.accepts = function( owner ) {
// Accepts only:
// - Node
// - Node.ELEMENT_NODE
// - Node.DOCUMENT_NODE
// - Object
// - Any
return owner.nodeType ?
owner.nodeType === 1 || owner.nodeType === 9 : true;
};
Data.prototype = {
key: //钥匙。功能是设置钥匙的值,如果cache[key]的值是undefined,赋值一个{};
set:
get:
access: //使用权,通道。功能是判断是获取还是设置
remove:
hasData:
discard:
};
data_user = new Data();data_priv = new Data();
在加载完jQuery后,会生成两个变量data_user ,data_priv ,在jQuery中相当于全局变量,并且每个对象都有catch属性和expando属性
$.data(document.body,'age',30)
工具方法$.data():
data: function( elem, name, data ) {
return data_user.access( elem, name, data );
},
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;
},
set: function( owner, data, value ) {
var prop,
unlock = this.key( owner ),//this指data_user
cache = this.cache[ unlock ];this指data_user
if ( typeof data === "string" ) {
cache[ data ] = value;
// Handle: [ owner, { properties } ] args
} else {
// 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
} else {
for ( prop in data ) {
cache[ prop ] = data[ prop ];
}
}
}
return cache;
},
key: function( owner ) {
if ( !Data.accepts( owner ) ) {
return 0;
}
var descriptor = {},
unlock = owner[ this.expando ];
// If not, create one
if ( !unlock ) {
unlock = Data.uid++;
// Secure it in a non-enumerable, non-writable property
try {
descriptor[ this.expando ] = { value: unlock };
Object.defineProperties( owner, descriptor );
// Support: Android < 4
// Fallback to a less secure definition
} catch ( e ) {
descriptor[ this.expando ] = unlock;
jQuery.extend( owner, descriptor );
}
}
// Ensure the cache object
if ( !this.cache[ unlock ] ) {
this.cache[ unlock ] = {};
}
return unlock;
},
Object.defineProperties():
Object.defineProperties(obj, {
'age': {
value: 24,
writable: true,
enumerable: true,
configurable: true
},
'sex': {
value: 'male',
writable: false,
enumerable: false,
configurable: false
}
});
console.log(obj);//Object {age: 24}
console.log(obj.age);//24
console.log(obj.sex);//male
<body jQuery2030134726371150463820.6999935407657176 = 1>
data_user .cache:{
1:{age:30}
}
data_user .cache:{
1:{age:30,
name:'hello' }
}