大家好,最近,我在学习Lodash这个工具库。Lodash最初是 Underscore
的分支,后来逐渐壮大后自立门户。Lodash 功能比 Underscore 更丰富,且 Underscore 已有3、4年没有更新,所以推荐使用 Loadash。但是和原生相比还是推荐使用ES6等。
所以我们一起来学习Lodash,今天打卡第二天,加油!
目录
1.前言
Lodash 和 Underscore 是非常优秀的当代JavaScript的工具集合框架,它们被前端开发者广泛地使用。但是,当我们现在是针对现代化浏览器进行开发时,很多时候我们利用的Underscore中的方法已经被ES5与ES6所支持了,如果我们希望我们的项目尽可能地减少依赖的话,我们可以根据目标浏览器来选择不用Lodash或者Underscore。
2 常见用法
在这部分我们介绍一些 Lodash 的常见的优雅的用法。主要是引起大家的学习兴趣,有更多优雅用法等待大家去发现。
_.random 随机数
// Naive utility method
function getRandomNumber(min, max){
return Math.floor(Math.random() * (max - min + 1)) + min;
}
getRandomNumber(15, 20);
// Lodash
_.random(15, 20);
_.get
获取一个嵌套很深的字段
//config 初始化为 null,需要从服务器端获取权限数据
let config = null;
ajax.get(url, function(data) {
// data = {basic: {delete: true}}
config = data;
});
//使用原生JS获取是否有删除权限
let isDeletable = false;
if (config && config.basic) {
isDeletable = config.basic.delete || false;
}
//使用lodash获取是否有删除权限
let isDeletable = _.get(config, 'basic.delete', false);
_.map
获取数组中每个对象的特定字段,并形成一个新的数组对应地,可以通过_.set({}, 'a.b.c', 1)
创建一个多级嵌套的对象。
//使用所有用户的 idCard 字段创建出一个数组
let users = [{ idCard: '20160512', name: '张三' }, { idCard: '20160513', name: '李四' }];
//使用原生JS
let idCards = users.map(function(user) {
return user.idCard;
});
//使用lodash
let idCards = _.map(model, 'idCard');
_.omit 筛选
大多数情况下,Lodash 所提供的辅助函数都会比原生的函数更贴近开发需求。在上面的代码中,开发者可以使用数组、字符串以及函数的方式筛选对象的属性,并且最终会返回一个新的对象,中间执行筛选时不会对旧对象产生影响。
_.pick 是 _.omit 的相反操作,用于从其他对象中挑选属性生成新的对象。
// Naive method: Remove an array of keys from object
Object.prototype.remove = function(arr) {
var that = this;
arr.forEach(function(key){
delete(that[key]);
});
};
var objA = {"name": "colin", "car": "suzuki", "age": 17};
objA.remove(['car', 'age']);
// {"name": "colin"}
// Lodash
objA = _.omit(objA, ['car', 'age']);
_.pick
取出对象的部分字段形成一个新对象
对应地,还有_.omit
方法表示删除部分字段形成一个新对象。
//在修改密码表单里,用户输入了如下字段并被封装到一个对象中
let form = {
password: '123456', //密码
repeatPassword: '123456', //重复密码
code: '5489', //验证码
};
//这里不直接使用delete删除字段,是因为该 form 对象与 DOM 进行了绑定。
//其中重复密码只用来在客户端校验,不需要发送给服务器
let data = {};
let fields = ['password', 'code'];
for (var i = 0; i < fields.length; i++) {
data[fields[i]] = form[fields[i]];
}
//使用lodash
let data = _.pick(form, 'password', 'code');
_.random
获取一个随机值
//获取[90, 100)之内的一个随机值
let min = 90;
let max = 100;
//使用原生JS
let random = Math.floor(Math.random() * (max - min)) + min;
//使用lodash
let random = _.random(min, max);
_.clamp
将一个数字修改成区间中的一个值
类似地,_.sample(['a', 'b', 'c'])
可以从数组中随机取出一个项目。
//使用原生JS
function applyRange(number) {
number = Math.max(number, this.props.min);
number = Math.min(number, this.props.max);
return number;
}
//使用lodash
let number = _.clamp(number, min, max);
_.once
确保一个函数只会执行一次
//使用原生JS
let inited = false;
function init() {
if (inited) return;
// init code
}
//使用lodash
let init = _.once(function() {
// init code
});
_.chain
链式操作
链接调用让代码更加整洁;避免了中间变量,避免了错误引用,让代码质量更有保证;_.chain
还提供了延迟计算特性,在显式或隐式调用value()
方法之前是不进行任何计算的,通过合并大大降低迭代次数。
下面是lodash
的官方文档中的一个例子。
var users = [{ user: 'barney', age: 36 }, { user: 'fred', age: 40 }, { user: 'pebbles', age: 1 }];
var youngest = _.chain(users)
.sortBy('age')
.map(function(chr) {
return chr.user + ' is ' + chr.age;
})
.first()
.value();
// → 'pebbles is 1'
_.cloneDeep 深拷贝
JavaScript 没有直接提供深拷贝的函数,但我们可以用其他函数来模拟,比如 JSON.parse(JSON.stringify(objectToClone)),但这种方法要求对象中的属性值不能是函数。Lodash 中的 _.cloneDeep 函数封装了深拷贝的逻辑,用起来更加简洁。
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
3 模块
Lodash 的工具函数很多,可以分为以下几类:数组(Array),集合(Collection),函数(Function),Lang(Lang),数学(Math),数字(Number),对象(Object),字符串(String),未分类工具函数(Util)。下面将会按类别介绍常见工具函数。
4 数组
获取子数组
函数名 | 简介 |
---|---|
slice | 获取元素第 m-n(不包含)个元素 |
tail | 获取出第一个元素之外的其他元素 |
initial | 获取出最后一个元素之外的其他元素 |
take | 从左侧开始获取任意数量的元素 |
takeRight | 从右侧开始获取任意数量的元素 |
takeWhile | 从左侧开始获取任意数量的元素,直到断言返回假值 |
takeRightWhile | 从右侧开始获取任意数量的元素,直到断言返回假值 |
drop | 丢掉前面几个元素,得到剩余元素 |
dropWhile | 丢掉前面几个元素知道迭代器返回假值,得到剩余元素 |
dropRight | 丢掉后面几个元素,得到剩余元素 |
dropRightWhile | 丢掉后面几个元素知道迭代器返回假值,得到剩余元素 |
数组常见操作
操作 | 不修改原数组 | 修改原数组 |
---|---|---|
移除 | without | pull |
相减 | difference | pullAll |
相减 | differenceBy | pullAllBy |
相减 | differenceWith | pullAllWith |
反转 | reverse | |
裁剪 | at | pullAt |
过滤 | filter | remove |
数组常见操作变种函数 by, with
有些函数还可以稍微变化一下,接受不同的参数,提供更多灵活性。
作用 | 函数名 | by | with |
---|---|---|---|
相减 | difference | differenceBy | differenceWith |
交集 | intersection | intersectionBy | intersectionWith |
并集 | union | unionBy | unionWith |
异或 | xor | xorBy | xorWith |
相减 | pullAll | pullAllBy | pullAllWith,跟difference不同的是,pullAll修改原数组 |
去重 | uniq | uniqBy | uniqWith |
去重 | sortedUniq | sortedUniqBy |
获取数组某个位置上的元素
函数名 | 主要参数-返回值 | 简介 |
---|---|---|
head | 数组=>元素 | 返回数组的第一个元素,和first相同 |
last | 数组=>元素 | 返回数组的最后一个元素,和head相反 |
nth | 数组=>元素 | 返回数组中某个位置上的元素 |
检测元素在数组中的索引
函数名 | 简介 |
---|---|
indexOf | 获取元素在数组中的索引 |
sortedIndexOf | 和indexOf功能一致,只是通过二分搜索方法 |
lastIndexOf | 获取元素在数组中的索引,最后一次出现 |
sortedLastIndexOf | 和lastIndexOf功能一致,只是通过二分搜索方法 |
findIndex | 寻找元素位置 |
findLastIndex | 寻找元素位置,从后往前 |