/**
* Computes a hash of an 'obj'.
* Hash of a:
* string is string
* number is number as string
* object is either result of calling $$hashKey function on the object or uniquely generated id,
* that is also assigned to the $$hashKey property of the object.
*
* @param obj
* @returns {string} hash string such that the same input will have the same hash string.
* The resulting string key is in 'type:hashKey' format.
*/
function hashKey(obj) {
var objType = typeof obj,
key;
if (objType == 'object' && obj !== null) {
if (typeof (key = obj.$$hashKey) == 'function') {
// must invoke on object to keep the right this
key = obj.$$hashKey();
} else if (key === undefined) {
key = obj.$$hashKey = nextUid();
}
} else {
key = obj;
}
return objType + ':' + key;
}
/**
* HashMap which can use objects as keys
*/
function HashMap(array){
forEach(array, this.put, this);
}
HashMap.prototype = {
/**
* Store key value pair
* @param key key to store can be any type
* @param value value to store can be any type
*/
put: function(key, value) {
this[hashKey(key)] = value;
},
/**
* @param key
* @returns the value for the key
*/
get: function(key) {
return this[hashKey(key)];
},
/**
* Remove the key/value pair
* @param key
*/
remove: function(key) {
var value = this[key = hashKey(key)];
delete this[key];
return value;
}
};
这是javascript封装的hashMap,先看下nextUid()的源码
var uid=["0","0","0"]
function nextUid() {
var index = uid.length;
var digit;
while(index) {
index--;
digit = uid[index].charCodeAt(0);
if (digit == 57 /*'9'*/) {
uid[index] = 'A';
return uid.join('');
}
if (digit == 90 /*'Z'*/) {
uid[index] = '0';
} else {
uid[index] = String.fromCharCode(digit + 1);
return uid.join('');
}
}
uid.unshift('0');
return uid.join('');
}
这里使用了数组,数组的element由0-9和a-z-A-Z组成,返回值为数组值组成的字符串,这里为什么使用unshift方法,而不是push(),如果使用push,代码如下=>
function nextUid1() {
//var index = uid.length;
var digit, index = 0;
while (uid[index] != undefined) {
digit = uid[index].charCodeAt(0);
if (digit == 57 /*'9'*/ ) {
uid[index] = 'A';
return uid.join('');
}
if (digit == 90 /*'Z'*/ ) {
uid[index] = '0';
} else {
uid[index] = String.fromCharCode(digit + 1);
return uid.join('');
}
index++;
}
uid.push('0');
return uid.join('');
}
我猜测不使用push的两个可能:
1.使用nextUid1和使用nextUid产生出的Uid,nextUid易读。
2.每次while循环,nextUid1的消耗大于nextUid。综合比较消耗,nextUid胜出。
接下来,我们看一下hashKey方法,在这里hashKey主要是用来将HashMap的key进行Unique String化的处理,这样就使得key可以为一个函数或者Object,并且会为其附带$$hashKey属性。这也是为什么在AngularJS下使用JSON.stringify()会有多余的$$hashKey。
这个HashMap 还是有一点一小题,就是new HashMap({1:1})的时候,会自动将key转换成string类型。