日期:2014-05-16  浏览次数:20360 次

js中实现Map
自己项目中用到了这个,记录下来,以便下次不用到处找
//***************************** Map javascript **************************

	function Map(linkItems) {
	    this.current = undefined; 
	    this._size = 0; 
	    if(linkItems === false){
	    	this.disableLinking(); 
	    } 
	}
	/**
	 * get currently map
	 * @return current object
	 */
	Map.noop = function() { 
	    return this; 
	}; 
	/**
	 * invalid operation
	 * @return
	 */
	Map.illegal = function() { 
	    throw new Error('invalid operation, the Map has been disable');
	}; 
	/**
	 * 
	 * @param obj
	 * @param foreignKeys
	 * @return
	 */
	Map.from = function(obj, foreignKeys) { 
	    var map = new Map; 
	    for(var prop in obj) { 
	        if(foreignKeys || obj.hasOwnProperty(prop)){
	        	map.put(prop, obj[prop]); 
	        } 
	    } 
	    return map; 
	}; 
	/**
	 * disable map
	 * @return
	 */
	Map.prototype.disableLinking = function() { 
	    this.link = Map.noop; 
	    this.unlink = Map.noop; 
	    this.disableLinking = Map.noop; 
	    this.next = Map.illegal; 
	    this.key = Map.illegal; 
	    this.value = Map.illegal; 
	    this.clear = Map.illegal; 
	    return this; 
	}; 
	/**
	 * return hash value eg: number 123
	 * @param value key/value
	 * @return
	 */
	Map.prototype.hash = function(value) { 
	    return (typeof value) + ' ' + (value instanceof Object ? (value.__hash || (value.__hash = ++arguments.callee.current)) : value.toString()); 
	}; 
	/**
	 * return map length
	 * @return
	 */
	Map.prototype.size = function() { 
	    return this._size;
	}; 

	Map.prototype.hash.current = 0; 
	/**
	 * get value by key
	 * @param key
	 * @return
	 */
	Map.prototype.get = function(key) { 
	    var item = this[this.hash(key)]; 
	    return item === undefined ? undefined : item.value; 
	}; 
	/**
	 * push the value into map
	 * @param key
	 * @param value
	 * @return
	 */
	Map.prototype.put = function(key, value) { 
	    var hash = this.hash(key); 
	    if(this[hash] === undefined) { 
	        var item = { key : key, value : value }; 
	        this[hash] = item; 
	        this.link(item); 
	        ++this._size; 
	    }else{
	    	this[hash].value = value;
	    } 
	    return this; 
	}; 
	/**
	 * delete value by key
	 * @param key
	 * @return
	 */
	Map.prototype.remove = function(key) { 
	    var hash = this.hash(key); 
	    var item = this[hash]; 
	    if(item !== undefined) { 
	        --this._size; 
	        this.unlink(item); 
	        delete this[hash]; 
	    } 
	    return this; 
	}; 
	/**
	 * clear map
	 * @return
	 */
	Map.prototype.clear = function() { 
	    while(this._size){
			this.remove(this.key()); 
		} 
	    return this; 
	}; 
	/**
	 * queue
	 * @param item
	 * @return
	 */
	Map.prototype.link = function(item) { 
	    if(this._size == 0) { 
	        item.prev = item; 
	        item.next = item; 
	        this.current = item; 
	    }else { 
	        item.prev = this.current.prev; 
	        item.prev.next = item; 
	        item.next = this.current; 
	        this.current.prev = item;
	    } 
	}; 
	Map.prototype.unlink = function(item) { 
	    if(this._size == 0){ 
	        this.current = undefined;
	    }else { 
	        item.prev.next = item.next; 
	        item.next.prev = item.prev; 
	        if(item === this.current){
	        	this.current = item.next; 
	        } 
	    } 
	}; 
	/**
	 * get next
	 * @return
	 */
	Map.prototype.next = function() { 
	    this.current = this.current.next; 
	    return this;
	}; 
	/**
	 * get current key
	 * @return
	 */
	Map.prototype.key = function() { 
	    return this.current.key; 
	}; 
	/**
	 * get current value
	 * @return
	 */
	Map.prototype.value = function() { 
	    return this.current.value; 
	}; 

	//***************************** Map javascript **************************