You don't need lodash

2,040 阅读2分钟

作为 lodash 重度依赖患者,最近在项目中翻了车,由于 tarowebpack 配置不会对 es6 moduletree shaking,导致 lodash 总是被全局打包+编译,严重影响了生产(打包)性能和开发(编译)效率。单独加载 chunk 就很有必要:

  • import xxx from 'lodash.xxx' 缺点,每次需要安装一下相关包,并且没代码提示
  • import xxx from 'lodash/xxx' 缺点,没有代码提示 Taro生态也有相应的 lodash babel 插件来做摇树,但作为一个年轻的前端,不妨模仿 lodash 的功能自己造几个轮子练习一下,以下是我平时使用率很高的一些lodash方法。

_.flatten(array)

[1, 2, [3, 4, [5]]] => [1, 2, 3, 4, 5]

lodash

_.flat([1, 2, [3, 4, [5]]], 2);
or
_.flattenDeep([1, 2, [3, 4, [5]]]);
or
_.flattenDepth([1, 2, [3, 4, [5]]], INFINITY);

diy

// es10 实现
[1, 2, [3, 4, [5]]].flat(INFINITY);

// es5 实现
function fla(arr, depth = 1) {
  const newArr = arr.reduce((memo, next) => {
    const element = next instanceof Array ? next : [next];
    memo.push(...element);
    return memo;
  }, []);

  return depth > 1 ? fla(newArr, depth - 1) : newArr;
}

_.fromPairs(pairs)

[['a', 1], ['b', 2]] => { 'a': 1, 'b': 2 }

lodash

_.fromPairs([['a', 1], ['b', 2]]);

diy

// es10 实现
Object.fromEntries([['a', 1], ['b', 2]]);

// es5 实现
function fromPairs(arr) {
  return arr.reduce((memo, next) => {
    memo[next[0]] = next[1];
    return memo;
  }, {});
}

_.cloneDeep(obj)

lodash

_.cloneDeep(obj);

diy

function cloneDeep(obj) {
  if (!obj instanceof Object) {
    return obj;
  }

  const newObj = {};
  Object.keys(obj).forEach((key) => {
    newObj[key] = cloneDeep(obj[key]);
  });

  return newObj;
}

_.chunk(array, [size=1])

['a', 'b', 'c', 'd'] => [['a', 'b'], ['c', 'd']]

lodash

_.chunk(['a', 'b', 'c', 'd'], 2);

diy

function chunk(arr, chunkSize = 1) {
  const tmp = [...arr];
  const cache = [];

  while (tmp.length) {
    cache.push(tmp.splice(0, chunkSize));
  }
  return cache;
}

chunk(['a', 'b', 'c', 'd'], 2);

_.curry(func, [arity=func.length])

lodash

const fp = curry((a, b, c) => a + b + c);
fp(1)(2)(3)

diy

function curry(fn) {
  const expectedArgs = fn.length;
  const curried = (...args) => {
    return args.length >= expectedArgs
      ? fn(...args)
      : (...args2) => curried(...[...args, ...args2]);
  };
  return curried;
}

_.omit(object, [paths])

{ a: 1, b: 2, c: 3 } => {a: 1}

lodash

_.omit(object, ['a', 'c']);

diy

function omit(obj, paths) {
  const objClone = { ...obj };

  objClone.forEach(path => Reflect.deleteProperty(objClone, path));
  return objClone;
}

_.merge(object, [sources])

lodash

_.merge(object, other);

diy

function merge(source, other) {
  if (!source instanceof Object || !other instanceof Object) {
    return other ?? source;
  }

  return Object.keys({ ...source, ...other }).reduce(
    (memo, next) => {
      // 递归合并 value
      memo[next] = merge(source[next], other[next]);
      return memo;
    },
    Array.isArray(source) ? [] : {}
  );
}

_.difference(array, [values])

[[1, 2, 3], [2, 3, 4]] => [1]

lodash

_.difference([1, 2, 3], [2, 3, 4]);

diy

function difference(arrs) {
  return arrs.reduce((memo, next) => memo.filter(item => !next.includes(item)))
}

TODO

lodash的fp方法,函数式编程大法好😄

_.compose(..., qs, clear, transfer)

diy

qs |> clear |> transfer