如何学习Lodash源码?
任意一名工程师都需要有读源码的经历,源码就是代码中最底层的实现逻辑,深入学习源码有利于提高我们的代码思维和实现复杂场景解决问题的能力,如果你是小白,那和我一起来探索源码的世界吧,今天要分享的是学习过程中的一些感受和心得
–Lodash源码
如何快速掌握一个新知识
学习最忌讳盲目,以为学了就是会了,实际上自己只是学了点皮毛,问起来什么都答不上,有目标地去学是非常重要的,那么我们需要去哪里找呢?
- AI(大模型的出现很大程度上已经改变了程序员的学习方式,使用AI可以提高我们的学习效率,也可以使用AI解决我们学习中的一些难题,学会使用大模型,让AI成为我们的学习工具)全球陆陆续续出现了很多AI,深入AI世界寻找适合自己的大模型
- 浏览器(浏览器的搜索殷勤可以帮助你全网搜索你想要的东西,范围比较广泛,你可以自由选取)
- 博客(如果你很着急想快速掌握一个知识,对于博客这种二次加工的产物,对你会有很大帮助)
- 文档(文档是相对全面的,不管是深度和广度,都非常详细,但是往往花点时间较多,并且文档比较于其他是比较枯燥的)
- 视频(视频也算是二次加工的东西(不是说二次不好的意思),视频相对来说文档理解起来更加快,但是如果你想深入学习某个东西,建议你看文档)
这里给大家推荐两种 :
快速掌握lodash(非源码)
深入学习lodash(源码)
从一个你最熟悉、最好奇的函数开始,逐个击破。 你的目标不是“读完 Lodash”,而是“读懂 _.get”。
- 入门级(推荐):_.chunk (数组分块), _.compact (移除假值), _.isString (判断类型)
- 进阶级:_.get (为什么它能安全地取嵌套属性?), _.debounce (防抖是怎么实现的?), _.cloneDeep (深拷贝到底有多深?)
今天分享两个函数
:
1.._chunk()
(看 _.chunk 的源码,你会学到它如何处理各种边界情况)
它是做什么的? 把一个数组,按照你指定的大小(size),切分成若干个新的小数组,最后返回一个包含这些小数组的新数组。
如何使用 :
const tags = ['js', 'go', 'css', 'html', 'node', 'react', 'vue', 'cpp'];// 把 'tags' 数组按每 3 个一组进行分块
const result = _.chunk(tags, 3);// => [['js', 'go', 'css'], ['html', 'node', 'react'], ['vue', 'cpp']]
源码:
function chunk(array, size, guard) {if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {size = 1;} else {size = nativeMax(toInteger(size), 0);}var length = array == null ? 0 : array.length;if (!length || size < 1) {return [];}var index = 0,resIndex = 0,result = Array(nativeCeil(length / size));while (index < length) {result[resIndex++] = baseSlice(array, index, (index += size));}return result;
}
问题:
- 如果 size 不是一个整数怎么办?
toInteger(size) 强制将其转换为整数。 - 如果 size 小于 1 怎么办? (例如 0, -2, 或 0.5)
Math.max(…, 0) 和 size < 1 的检查会联手处理。 - 如果原数组是空的怎么办?
const length = array == null ? 0 : array.length 和 !length 检查会处理。
2._.filter()
它是做什么的? 遍历一个集合(数组或对象),返回一个新数组,新数组中只包含那些通过了“断言函数”(你提供的测试函数)的元素。
亮点:
- 用于对象 :原生 filter 只能用于数组。
- 提供了“快捷方式” :这是 Lodash 的精髓之一。
如何使用:
const users = [{ 'user': 'barney', 'age': 36, 'active': true },{ 'user': 'fred', 'age': 40, 'active': false },{ 'user': 'pebbles', 'age': 1, 'active': true }
];// 用法 1:和原生 filter 类似的函数写法
const activeUsers = _.filter(users, function(user) {return user.active; // => [barney, pebbles]
}); // 用法 2:使用“属性值”快捷方式
const activeUsers2 = _.filter(users, { 'active': true });
// => [barney, pebbles]// 找出所有 'age' 为 1 且 'active' 为 true 的用户
const babyUser = _.filter(users, { 'age': 1, 'active': true });
// => [pebbles]
源码:
function filter(collection, predicate) {var func = isArray(collection) ? arrayFilter : baseFilter;return func(collection, baseIteratee(predicate, 3));
}
- predicate 是个函数,它就直接当测试函数用。
- predicate 是个对象(像 { ‘active’: true }),它就会在内部调用一个叫 baseMatches 的辅助函数,这个函数会生成一个新的函数,这个新函数的作用就是去检查元素是否匹配你给的模板对象。
希望大家可以有所收获