/** * 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类型。