【5天打卡】学习Lodash的第五天——总结篇

Lodash 含有 Array, Collection, Date, Function, Lang, Math, Number, Object, String 等多个功能模块,总共几百个功能函数。官方文档上以字典顺序排序,不容易总结记忆。通过这5天的学习,我们对这一框架进行总结。主要从lodash的使用优势和迷人细节来辩证看待这一框架。lodash函数的实现非常严谨、高效、兼容性强,以及具有一定的前瞻性。但考虑与ES6部分重合,也不一定要用它完全替代。

目录

 lodash优势:

1.lodash在具体使用时按需引入,避免引入不必要的代码:

2.lodash提供的api具有ES6没有的功能,可以省去很多复杂逻辑,优雅而便捷;

3.lodash 的所有操作都是 null-safe 的,而 ES6 完全不考虑

4.lodash 的操作(例如 forEach)都是对对象数组都可用的,而 ES6 原生方法往往只对数组有效。

5.Lodash 还提供了几乎所有浏览器的兼容,很多浏览器对ES6-12的兼容还没完全,所以先使用lodash替代。

6.lodash对于server 端、框架或是工具库开发而言,如果无法预测代码会跑在什么环境,有 lodash 能少考虑很多兼容的问题少做很多测试。

7.lodash很多方法都提供了 path 以及一些很方便的参数,可以大幅度减少代码量.

8.lodash很多immutable,生成新的数据,不影响老数据。是而 JS 原生的 Array 方法,有一些是 mutable 的,有一些是 immutable 的,导致很多坑。

Lodash的迷人细节:

1.length = start > end ? 0 : ((end - start) >>> 0)

2.arr instanceof Array

3._.eq(value, other)

4._.isNaN

5. (-0).toString() === '0'?苦恼!

6. JS 的世界里,谁不能转化为数字?

7. _.repeat 的优化手段


所以我们一起来学习Lodash,今天打卡第五天,加油!

 lodash优势:

1.lodash在具体使用时按需引入,避免引入不必要的代码:

// 方式1:引入整个lodash对象
import _ from "lodash";

// 方式2:按模块引入
 import map from 'lodash/fp/map';

// 方式3:按名称引入特定的函数
import { cloneDeep } from "lodash"; 

2.lodash提供的api具有ES6没有的功能,可以省去很多复杂逻辑,优雅而便捷;

const obj={a: {b: {c: {one: 'blue', two: 'red'}}}}
let tmp = obj && obj.a && obj.a.b && obj.a.b.c
tmp && Object.keys(tmp).map(key => tmp[key])  // / ["blue", "red"]
// lodash 优雅简化
const obj={a: {b: {c: {one: 'blue', two: 'red'}}}}
_.map(_.get(obj, 'a.b.c'), (item, key)=> item)   // ["blue", "red"]

3.lodash 的所有操作都是 null-safe 的,而 ES6 完全不考虑

4.lodash 的操作(例如 forEach)都是对对象数组都可用的,而 ES6 原生方法往往只对数组有效。

5.Lodash 还提供了几乎所有浏览器的兼容,很多浏览器对ES6-12的兼容还没完全,所以先使用lodash替代。

6.lodash对于server 端、框架或是工具库开发而言,如果无法预测代码会跑在什么环境,有 lodash 能少考虑很多兼容的问题少做很多测试。

7.lodash很多方法都提供了 path 以及一些很方便的参数,可以大幅度减少代码量.

8.lodash很多immutable,生成新的数据,不影响老数据。是而 JS 原生的 Array 方法,有一些是 mutable 的,有一些是 immutable 的,导致很多坑。

Lodash的迷人细节:

1.length = start > end ? 0 : ((end - start) >>> 0)

在有用到 Array.length 的场景,可用 >>> 0 做参数防护,在 JS 中,Array.length 是一个 32 位无符号整型数字,而通过无符号位移运算 >>> 0,就是为了确保我们得到的正确的 length 值,它总是能得到一个 32-bit unsigned ints 。

2.arr instanceof Array

我们会用 instanceof 去判断实例与类之间的关系,但是这种关系可靠吗?

arr instanceof Array 为 true 肯定 arr 就是一个数组,但是为 false 是不是就表示 arr 肯定不是数组呢?

不能!在有多个 frame 的时候就不能...

let xArray = window.frames[0].Array; // origin from iframe's window
let arr = new xArray(1, 2, 3);

arr instanceof Array; // false

Array.isArray(arr); // true

也就是,你以为的并不都是你以为的 ... 虽然我们平时不常会有多个 frame 间这种级别的类的混用,但是以防万一...

通常,在需要判断是否是数组时,可以使用 Array.isArray 或者它的 Polyfill:

if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
} 

3._.eq(value, other)

判断 value 和 other 是否(强)相等,在 ECMA 规范中对于相等其实是有明确的定义的,其中 NaN === NaN,但是在 JS 中,NaN 是不与任何值相等的,包括自身,而 Lodash 弥补了这部分的不足,那怎么判断 NaN === NaN 呢?

function eq(value, other) {
  return value === other || (value !== value && other !== other)
}

我们知道 NaN 是唯一个不与自身相等的值,因此可以通过这个特性分别得到 value 和 other 是否是 NaN,如果是,则两者相等,返回 true.

4._.isNaN

如何判断是否是 NaN ?

通过 isNaN 全局方法?

isNaN('x')       // true

isNaN(NaN)       // true

isNaN(0)         // false

全局方法 isNaN 是有坑的,它的 NaN 定义估计真的是 not a number, 而不是值得 NaN 这个s数值,也就是除了 NaN, 对于 不能转化为数字 的情况都会返回 true ... 糟心!其实这个问题已经在 ES6 中被改善啦,Number.isNaN分分钟教isNaN 做人,Number.isNaN 只会对 NaN 返回 true, 其他情况都是 false...

5. (-0).toString() === '0'?苦恼!

-0 的 toString 竟然没有保留 - ,坑爹嘛不是...

但是,_.toString(-0) === '-0' ,如何做的?

// 一系列的前置检查和转化后...
const INFINITY = 1 / 0; // 手动 INFINITY
const res = `${value}`;

if (res === '0' && 1 / value === -INFINITY) {
  return '-0';
} else {
  return res;
}

6. JS 的世界里,谁不能转化为数字?

数字、数字字符串肯定是可以的...

对象?或者非数字的字符串?它们也能得到 NaN

Symbol !

Number('xx')          // NaN

Number(new Object())  // NaN

Number(Symbol())
// --> Uncaught TypeError: Cannot convert a Symbol value to a number

另外,Symbol 可以显示的转化为 String 和 Boolean, 但是,不能进行任何隐式转换,也就是不能对 Sybmol 进行运算,比如:

const symbol = Symbol();

1 + symbol       // TypeError

'1' + symbol     // TypeError

// 可显示转化为 布尔 和 字符串
Boolean(symbol)  // true

String(symbol)   // "Symbol()"

7. _.repeat 的优化手段

_.repeat([str = ''], [times = 1])

指定 string 重复 n 次输出,可以很简单的通过循环实现:

const repeat = (str = '', times = 1) => {
  let res = str;

  while (--times) {
    res += str;
  }

  return res;
}

repeat('6', 3); // 666

Easy ? 好像不是特别完美吧,设想 repeat('6', 4) 按照上述实现需要循环 4 次,但是其实是可以通过两次操作就把最终结果拼接出来的,就相当于 repeat(repeat('6', 2), 2) ,所以这块是有优化空间的,来看优化后的算法:

const repeat = (str = '', times = 1) => {
    let result = '';

    if (!str || times < 1) {
        return result;
    }

    do {
        if (times % 2) {
            result += str;
        }

        times = Math.floor(times / 2);

        if (times) {
            str += str;
        }
    } while (times)

    return result;
}

性能对比:repeat('hello world', 100000) 测试的 benchmark:

远远超出 ...

总结:Lodash这个库真香,但是还是要辩证看待,需要了解它的安全漏洞,安全避开,还要了解它部分修改原数据的api,然后注意按需引入。

以上就是今天的学习,欢迎关注我,大家一起进步!

欢迎点赞,评论,谢谢!~

参考学习:

Lodash 源码中的那些迷人的细节 - 知乎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值