1、Lodash是什么?
Lodash是一个一致性、模块化、高性能的 JavaScript 实用工具库。它内部封装了诸多对字符串、数组、对象等常见数据类型的处理函数,
其中部分是目前ECMAScript尚未制订的规范,但同时被业界所认可的辅助函数。
2、为什么会出现Lodash?
任何一个库和框架的出现都是为了解决问题的,那么Lodash是解决什么问题的?
官方文档上的定义:
Lodash 通过降低 array、number、objects、string 等等的使用难度从而让 JavaScript 变得更简单。 Lodash 的模块化方法 非常适用于:
- 遍历 array、object 和 string
- 对值进行操作和检测
- 创建符合功能的函数
Lodash就是这样的一个工具库,方便我们在日常的开发中对数据的操作,特别是数组和对象的各种读写等操作,比如去重,拷贝,合并,过滤,求交集,求和等等,提高开发效率。
3、Lodash可用性怎么样?
每天使用npm安装Lodash的数量在百万级以上,这在一定程度上证明了其代码的健壮性。
在github上的数据也证明了这一点:
Core build (~4 kB gzipped) Full build (~24 kB gzipped)
完整版导出min版本的话大概78k,建议用的时候要根据场景按需引入 或者打包的时候不要打包进bundle里
4、Lodash怎么用?有什么特点?
(1) 安装
Lodash地址
(2) 使用
api文档 使用范例
(3) 功能简介(版本4.17)
- Array,适用于数组类型,比如增删改查、填充数据(
_.fill
)、查找元素(_.findeIndex
)、数组分片(_.chunk
)等操作 - Collection,适用于数组和对象类型,部分适用于字符串,比如遍历、分组、查找、过滤等操作
- Function,适用于函数类型,比如节流、延迟、缓存、设置钩子等操作
- Lang,普遍适用于各种类型,常用于执行类型判断和类型转换、深拷贝
- Math,适用于数值类型,常用于执行数学运算(最大值、最小值求和)
- Number,适用于生成随机数,比较数值与数值区间的关系
- Object,适用于对象类型,常用于对象的创建、扩展、类型转换、检索、集合等操作
- Seq,常用于创建链式调用,提高执行性能(惰性计算)
- String,适用于字符串类型
- Util,一些工具函数,比如_.attmpt 替代 try-catch 的方式,当解析 JSON 出错时,该方法会返回一个Error对象
- Properties, 模板方法 ES6的模板字符串和这个功能很像(对模板字符串进行了正则解析,将需要填入数据的位置预留出来,拼接成一个字符串)
- Methods, 对lodash函数的引用
(4) 优势
1、函数式编程风格
常用核心概念纯函数(注释1)、柯里化函数、声明式和命令式等
2、链式调用和惰性求值
//显式调用
var users = [
{ 'user': 'barney', 'age': 36 },
{ 'user': 'fred', 'age': 40 },
{ 'user': 'pebbles', 'age': 1 }
];
var youngest = _
.chain(users) //可以链式调用的关键 Returns the new lodash wrapper instance.
.sortBy('age')
.map(function(o) {
return o.user + ' is ' + o.age;
})
.head()
.value();
// => 'pebbles is 1'
复制代码
//隐式调用
var youngest = _(users) // 不需要显式的使用chain关键字
.sortBy('age')
.map(function(o) {
return o.user + ' is ' + o.age;
})
.head()
复制代码
注意两者的区别:
为什么要多出来一个 .value(),而不是直接出结果呢?那是因为可能要等待延时(Deferred execution)数据的到来,再执行取值。这就是我们常说的Lazy evaluation (延迟计算/惰性求值)
(value)建立了一个隐式链对象,可以把那些能操作并返回 arrays(数组)、collections(集合)、functions(函数)的”.Methods”(lodash的函数)串起来。 那些能返回“唯一值(single value)”或者可能返回原生数据类型(primitive value)会自动结束链式反应。 而显式链则用.chain. 的方式实现延迟计算,即:求值操作等到 _value()被调用时再执行。
说到惰性求值官方这样介绍的:
惰性求值(Lazy Evaluation),又译为惰性计算、懒惰求值,也称为传需求调用(call-by-need),是计算机编程中的一个概念,它的目的是要最小化计算机要做的工作。 惰性求值中的参数直到需要时才会进行计算。这种程序实际上是从末尾开始反向执行的。它会判断自己需要返回什么,并继续向后执行来确定要这样做需要哪些值。
以How to Speed Up Lo-Dash ×100? Introducing Lazy Evaluation.中这个例子为例
function priceLt(x) {
return function(item) { return item.price > x; };
}
var gems = [
{ name: 'Sunstone', price: 4 }, { name: 'Amethyst', price: 15 },
{ name: 'Prehnite', price: 20}, { name: 'Sugilite', price: 7 },
{ name: 'Diopside', price: 3 }, { name: 'Feldspar', price: 13 },
{ name: 'Dioptase', price: 2 }, { name: 'Sapphire', price: 20 }
];
var chosen = _(gems).filter(priceLt(10)).take(3).value();
复制代码
函数的目的是对数组gems进行筛选,选出3个price小于10的数据。
(1) 一般的做法(不用lodash)
var chosen = _(gems).filter(priceLt(10)).take(3)
先执行filter方法,遍历gems数组(长度为10),取出符合条件的数据:
[
{ name: 'Sunstone', price: 4 },
{ name: 'Sugilite', price: 7 },
{ name: 'Diopside', price: 3 },
{ name: 'Dioptase', price: 2 }
]
复制代码
然后,执行take方法,提取前3个数据。 总共遍历的次数为:10+3 执行的示例图如下:
(2) 惰性求值做法
以下是实现的思路:
- _(gems)拿到数据集,缓存起来
- 遇到filter方法,先记下来
- 遇到take方法,先记下来
- 遇到value方法,说明时机到了
- 把小本本拿出来,看下要求:要取出3个数,price<10
- 使用filter方法里的判断方法priceLt对数据进行逐个裁决
一共只执行了5次,就把结果拿到
惰性计算的特点:1、 延迟计算,把要做的计算先缓存,不执行
2、 数据管道,逐个数据通过“裁决”方法,在这个类似安检的过程中,进行过关的操作,最后只留下符合要求的数据
3、 触发时机,方法缓存,那么就需要一个方法来触发执行。lodash就是使用value方法,通知真正开始计算
5、为什么不用ES6完全替换Lodash?
目前替换不了,就对null值容错方面上讲,Lodash有着更好的性能 比如我们想从一组对象中摘取出某个属性的值
let arr = [{ n: 1 }, { n: 2 }]
// ES6
arr.map(obj => obj.n)
// Lodash
_.map(arr, 'n')
复制代码
当对象类型的嵌套层级很多时:
let arr = [
{ a:[{ n:1 }]},
{ b:[{ n:1 }]}
]
// ES6
arr.map(obj => obj.a[0].n)
// TypeError: 属性 'a' 在 arr[1] 中未定义
// Lodash
_.map(arr, 'a[0].n')
// => [1, undefined]
复制代码
许多 Lodash 提供的功能已经可以用 ES6 来替换,有些Lodash方法,ES6是没有的。Lodash 这样的类库也在不断推动 JavaScript 语言本身的发展
资料
Lodash git地址 Lodash中文文档 显试调用与隐性调用
注释1:纯函数:对于相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用,也不依赖外部环境的状态的函数,比如redux中reducer。