underscore源码学习笔记(二)

2、数组

  1. 首先说说里面遇见的比较多的一个值:void 0, void自己是一个操做符,对表达式求值,并返回 undefined。因此void 0 其实就是等于undefined的,因为undefined自己在浏览器中的差别,有些undefined能够被重写,因此使用void 0 代替undefined更加安全。void(0)也经常在锚连接中这样使用:href = javascript:void(0); ,用于取消a标签的默认行为
  2. 接下来开始数组部分的源码学习:
  • 相对复杂的一个函数:flatten,用于将嵌套的数组转换为1维数组,或者减小一个维度(shallow为ture时),而且能够配置起始位置。
var flatten = function(input, shallow, strict, startIndex) {
    var output = [], idx = 0;
    for (var i = startIndex || 0, length = input && input.length; i < length; i++) {
      var value = input[i];
      if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
        if (!shallow) value = flatten(value, shallow, strict);
        var j = 0, len = value.length;
        output.length += len;
        while (j < len) {
          output[idx++] = value[j++];
        }
      } else if (!strict) {
        output[idx++] = value;
      }
    }
    return output;
};

主要是利用了递归,首先循环数组,若是数组内部元素是数组,则对其递归调用自身函数。不然直接将其值赋给Output数组,原理相似于对象的深度clone函数。javascript

function cloneObject(src) {
    var obj;
    if (typeof src === 'object') {
    // 须要注意的是对typeof对null也返回'object'
        if (src === null) {
            obj = null;
        } else {
            obj = {};
            for (var k in src) {
                if (src.hasOwnProperty(k)) {
                    obj[k] = (typeof src[k] === 'object') ? cloneObject(src[k]) : src[k];
                }
            }
        }
    } else {
        obj = src;
    }
    return obj;
}
  • _.uniq函数,主要方法:
for (var i = 0, length = array.length; i < length; i++) {
      var value = array[i];
      var result = [];
      if (!_.contains(result, value)) {
        result.push(value);
        }
return result;

方法相似于经常使用的去重方法,定义一个空对象,将数组每项的值做为对象的属性,检测对象的属性是否存在,若是不存在,则将其push到结果数组中,并给这个属性设值,这样下次有相同的值,那么这个属性就是存在的。这里是依赖内部的_.contains函数来实现的。java

for (var i = 0, length = array.length; i < length; i++) {
      var value = array[i];
      var result = [];
      var a = {};
      if (!a[value]) {
        a[value] = 1;
        result.push(value);
}
return result;
  • indexOf、findIndex、lastIndexOf都是经过循环数组加if比较判断,比较清楚。
  • _.sortedIndex函数没有搞太懂。API说是使用二分查找肯定value在list中的位置序号,value按此序号插入能保持list原有的排序。
_.sortedIndex = function(array, obj, iteratee, context) {
    iteratee = cb(iteratee, context, 1);
    var value = iteratee(obj);
    var low = 0, high = array.length;
    while (low < high) {
      var mid = Math.floor((low + high) / 2);
      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
    }
    return low;
};

-ps: 发现_.range里一个var range = Array(length);这种不加new的,还有其余库里new调用构造函数不加括号的,js真的很灵活。。数组

相关文章
相关标签/搜索