[转帖]Mootools源码分析-03 -- Hash

//哈希表,Native化作为内置对象
var Hash =new Native({

//族名,类名,用于$type方法的精准类型判断
name: 'Hash',

initialize:
function(object) {

//对于哈希表的实例,复制副本以解除两者的引用/链接关系
if ($type(object) =='hash') ōbject = $unlink(object.getClean());

//再复制到当前实例
for (var key in object) this[key] = object[key];
returnthis;
}
});

//对哈希表的扩展的实现
Hash.implement({

//哈希表长度(键值数统计,不包括值型为函数的)
getLength: function() {
var length =0;
for (var key inthis) {
//hasOwnProperty判断是否具有指定名称的属性,注意是属性,不包括方法
if (this.hasOwnProperty(key)) length++;
}
return length;
},

//迭代,同时是只遍历属性,这个也很符合实际使用的情况
forEach: function(fn, bind) {
for (var key inthis) {
if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this);
}
},

//复制一个副本,不知道为什么用这个不容易理解的名字
getClean: function() {
var clean = {};
for (var key inthis) {
if (this.hasOwnProperty(key)) clean[key] =this[key];
}
return clean;
}

});

//将each作为forEach的别名
Hash.alias('forEach', 'each');

//转为哈希表的快捷方式
function $H(object) {
returnnew Hash(object);
};

//额外的扩展
Hash.implement({

//hasOwnProperty的快捷方式
has: Object.prototype.hasOwnProperty,

//根据值找对应的键
keyOf: function(value) {
for (var key inthis) {
if (this.hasOwnProperty(key) &&this[key] === value) return key;
}
returnnull;
},

//查找是否存在指定值
hasValue: function(value) {
return (Hash.keyOf(this, value) !==null);
},

//数据扩展,会覆盖原数据
extend: function(properties) {
Hash.each(properties,
function(value, key) {
Hash.set(
this, key, value);
},
this);
returnthis;
},

//合并,不包括重复项
combine: function(properties) {
Hash.each(properties,
function(value, key) {
Hash.include(
this, key, value);
},
this);
returnthis;
},

//探险指定键值
erase: function(key) {
if (this.hasOwnProperty(key)) deletethis[key];
returnthis;
},

//根据键名读取值
get: function(key) {
return (this.hasOwnProperty(key)) ?this[key] : null;
},

//设置键-值
set: function(key, value) {
if (!this[key] ||this.hasOwnProperty(key)) this[key] = value;
returnthis;
},

//清空哈希表
empty: function() {
Hash.each(
this, function(value, key) {
deletethis[key];
},
this);
returnthis;
},

//包含新键-值,如果旧数据中不存在该键名
include: function(key, value) {
var k =this[key];
if (!$defined(k)) this[key] = value;
returnthis;
},

//类似Array对象的map方法,区别在于传给fn方法的参数
map: function(fn, bind) {
var results =new Hash;
Hash.each(
this, function(value, key) {
results.set(key, fn.call(bind, value, key,
this));
},
this);
return results;
},

//类似Array对象的filter方法,区别在于传给fn方法的参数
filter: function(fn, bind) {
var results =new Hash;
Hash.each(
this, function(value, key) {
if (fn.call(bind, value, key, this)) results.set(key, value);
},
this);
return results;
},

//类似Array对象的every方法,区别在于传给fn方法的参数
every: function(fn, bind) {
for (var key inthis) {
if (this.hasOwnProperty(key) &&!fn.call(bind, this[key], key)) returnfalse;
}
returntrue;
},

//类似Array对象的some方法,区别在于传给fn方法的参数
some: function(fn, bind) {
for (var key inthis){
if (this.hasOwnProperty(key) && fn.call(bind, this[key], key)) returntrue;
}
returnfalse;
},

//获取哈希表中的所有键,以数组返回
getKeys: function() {
var keys = [];
Hash.each(
this, function(value, key) {
keys.push(key);
});
return keys;
},

//获取哈希表中的所有值,以数组返回
getValues: function() {
var values = [];
Hash.each(
this, function(value) {
values.push(value);
});
return values;
},

//将哈希表数据转为表单提交形式的查询串
toQueryString: function(base) {
var queryString = [];
Hash.each(
this, function(value, key) {
if (base) key = base +'['+ key +']';
var result;
switch ($type(value)) {
case'object':
result
= Hash.toQueryString(value, key);
break;
case'array':
var qs = {};
value.each(
function(val, i) {
qs[i]
= val;
});
result
= Hash.toQueryString(qs, key);
break;
default:
result
= key +'='+ encodeURIComponent(value);
}
if (value != undefined) queryString.push(result);
});
return queryString.join('&');
}

});

//分别为keyOf和hasValue建立indexOf和contains的别名方法
Hash.alias({keyOf: 'indexOf', hasValue: 'contains'});
posted @ 2011-08-28 13:11  穆乙  阅读(201)  评论(0编辑  收藏  举报