AngularJS-源码阅读(三)

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


转载于:https://my.oschina.net/myprogworld/blog/208404

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值