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

原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-400344

原作者:我佛山人

 

 

//哈希表,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];
        
return this;
    }
});

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

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

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

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

});

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

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

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

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

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

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

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

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

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

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

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

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

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

    
//类似Array对象的map方法,区别在于传给fn方法的参数
    map: function(fn, bind)    {
        
var results = new Hash;
        Hash.each(
thisfunction(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(
thisfunction(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 in this)    {
            
if (this.hasOwnProperty(key) && !fn.call(bind, this[key], key))    return false;
        }
        
return true;
    },

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

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

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

    
//将哈希表数据转为表单提交形式的查询串
    toQueryString: function(base)    {
        
var queryString = [];
        Hash.each(
thisfunction(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 @ 2009-10-22 10:44  webgis松鼠  阅读(268)  评论(0)    收藏  举报