underscore.js源码小记

 

写在前面

underscore.js是一个js的工具集,用于方便地处理数组、对象等,通过源码的学习,略微了解一些实现过程,与大家分享

1、判断对象与数组
var length = arrayOrobject.length;
if(length === +length) {
    console.log(typeof arrayOrobject) // array
}
else{
    console.log(typeof arrayOrobject) // object
}
2、true && 数据类型
console.log(true && undefined); // undefined
console.log(true && 1);	  // 1
console.log(true && 'a');   // a
console.log(true && [1,2,3]);  // [1,2,3]
console.log(true && {x:1,y:2}); // {x:1,y:2}
console.log(true && function(){}); // [Function]
3、数组扁平化处理
// eg:
//_.flatten([1, [2], [3, [[4]]]]);
//=> [1, 2, 3, 4];

/**
 * 数组扁平化处理
 * @param {array} input 输入数组
 * @param {boolean} shallow 表面转换 false:遍历,true:不遍历
 * @param {boolean} strict 严格模式
 * @param {number} startIndex 开始序号
 */
var flatten = function (input, shallow, strict, startIndex) {
    var output = [],    // 结果数组
      idx = 0,  // 结果数组序号,全局,可递增
      value;    // 结果数组对应值
    for (
      var i = startIndex || 0, length = input && input.length;  // 短路写法,做判断
      i < length;
      i++
    ) {
      value = input[i];
      // 如果是数组结构则递归调用
      if (
        value &&
        value.length >= 0 &&
        (_.isArray(value) || _.isArguments(value))
      ) {
        //flatten current level of array or arguments object
        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;
  };
4、Boolean强制类型转换
Boolean(0)    // false
Boolean(1)    // true
Boolean('')     // true
Boolean({})     // true
Boolean([])     // true
Boolean(function(){})    // true
5、arguments

arguments 是一个对应于传递给函数的参数的类数组对象,类似于Array,但除了length属性和索引元素之外没有任何Array属性。

arguments转为数组

var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);

// ES2015
const args = Array.from(arguments);
const args = [...arguments];
6、缓存

源码中使用的方法不太明晰,这里采用此法。

  const memorize = function(fn) {
    const cache = {}       // 存储缓存数据的对象
    return function(...args) {        // 这里用到数组的扩展运算符
      const _args = JSON.stringify(args)    // 将参数作为cache的key
      return cache[_args] || (cache[_args] = fn.apply(fn, args))  // 如果已经缓存过,直接取值。否则重新计算并且缓存
    }
  }
  const add = function(a, b) {
    console.log('开始缓存')
    return a + b
  }

  const adder = memorize(add)
  
    
  // console.log(adder(2, 6))    // 输出结果: 开始缓存 8        // cache: { '[2, 6]': 8 }
  // console.log(adder(2, 6))    // 输出结果: 8                //cache: { '[2, 6]': 8 }
  // console.log(adder(10, 10))  // 输出结果: 开始缓存 20    // cache: { '[2, 6]': 8, '[10, 10]': 20 }


posted @ 2020-04-17 11:05  mangata  阅读(126)  评论(0)    收藏  举报