源码学习----underscore

来源:互联网 发布:linux 查看文件夹属性 编辑:程序博客网 时间:2024/05/11 23:10

以前在网上做过一个面试题,在一个有序的数组查找特定值,如果存在返回数组下标,否则将数值插入数组中。我的之前做法在这里!

通过进一步学习underscoreJS,发现可以这么写

var arr = [10,20,30], value = 35;var location = _.sortIndex( arr, value);arr[location] == value || arr.splice( location, 0, value); 
如上所示,代码简单了很多!那效率究竟怎么样呢?看到underscore的源码发现源码中利用的是二分查找,时间复杂度是logn,而我那个就是n,差了不仅一点点。

为什么underscore这么好?因为它关注重点,功能专一

_.sortedIndex = function(array, obj, iterator, context) {    iterator = lookupIterator(iterator);    var value = iterator.call(context, obj);    var low = 0, high = array.length;    while (low < high) {      var mid = (low + high) >>> 1;      iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;//why?    }    return low;  };
上面的代码为什么这么写?难道是保留上下文才这么写的吗?在上面的代码中至少学到了

1.位运算;

2.函数递归调用与闭包的使用。


第二点  each方法的使用

在underscore.js中很多的函数都是为集合服务的,里面包括很多的迭代操作!

var each = _.each = _.forEach = function(obj, iterator, context) {    if (obj == null) return obj;    if (nativeForEach && obj.forEach === nativeForEach) {//nativeForEach      obj.forEach(iterator, context);    } else if (obj.length === +obj.length) {//array      for (var i = 0, length = obj.length; i < length; i++) {        if (iterator.call(context, obj[i], i, obj) === breaker) return;      }    } else {//object      var keys = _.keys(obj);      for (var i = 0, length = keys.length; i < length; i++) {        if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;      }    }    return obj;  };
函数中首先定义局部变量,在作用域下方便使用。

1.使用本地的forEach的方法。

2.判断数组的情况

3.判断对象的情况。判断对象的情况的时候特别有意思的一点,它没有像jQuery在对象中为每个对象给出0,1,2,3等属性,而是将属性存为属性数组,

然后遍历‘属性数组’,取出对象中属性对应的值。

_.keys = function(obj) {    if (!_.isObject(obj)) return [];    if (nativeKeys) return nativeKeys(obj);    var keys = [];    for (var key in obj) if (_.has(obj, key)) keys.push(key);    return keys;  };



0 0
原创粉丝点击