资讯专栏INFORMATION COLUMN

Lodash的学习笔记(一)有意思的API

BingqiChen / 2202人阅读

摘要:是函数柯里化的函数。例子柯里化有个常见作用参数复用构建高阶函数延迟计算。是的,它其实就是柯里化的具体应用构建高阶函数。这个是我认为的中最有意思的方法。不过要注意最后的。这同样是用来组合高阶函数的一个方法。

最近在学习JS函数式编程相关的内容,于是详细的翻看了Lodash的文档,感到别有洞天。这里把自己对一些API的使用和看法做个笔记记录下。

Array _.head/_.last

例子:

_.head([1, 2, 3]);
// → 1

_.last([1, 2, 3]);
// → 3

分别可以抽取数组第一个元素的值和最后一个元素的值。咋看之下觉得很无聊。但是跟下面两个结合起来就厉害。

_.tail/_.initial

例子:

_.tail([1, 2, 3]);
// → [2, 3]

_.initial([1, 2, 3]);
// → [1, 2]

也如字面描述一般容易理解的函数。但是结合上面的两个函数就产生很大能量。

首先看一个针对数组尾部特殊化处理的例子:

let names=["fred", "barney", "pebbles"];

_.initial(names).join(", ") +
(_.size(names) > 1 ? ", & " : "") + _.last(names);

// → "fred, barney, & pebbles"

怎么样比简单的写for+if else优雅很多吧。接着我们来看看递归求和:

function sum(arr){
    return _.head(arr) ? 
    ( _.head(arr) + sum( _.tail(arr) ) ) :
    0;
}

Tips

1)其实好像数组都可以表现为

[a, [b, [c .....]]]

然后再将其扁平化的结果。 是不是?所以结合这四个函数,很多数组遍历的操作都可以改写成递归的方式。虽然性能可能略差,但是可读性反而更强了(并非所有的递归都一定损耗性能,详细可以去了解下JIT优化)。

2)但是在ES6中,更推荐优先使用数组的解构。

_.zip

例子:

_.zip(["fred", "barney"], [30, 40]);
// → [["fred", 30], ["barney", 40]]

_.zip(*array) 将几个数组按照位置组成新的数组,返回数组列表。这个方法就有点像SQL里面select两个列的情况。对重组数据结构非常有帮助。

_.unzip

既然lodash是个函数库,那有zip肯定也有他的逆运算unzip。这里就不举例了。unzip其实可以看作对ES6数组解构的补充,应用的场景也是十分相似的。

Collection _.map/_.reduce/_.filter

这三个函数其实早就名声在外,就不举例了。列出来只是为了提醒,遍历集合可不仅仅只有_.each。任何时候都优先考虑这些函数。

_.every/_.some

例子:

let users = [
  { "user": "barney", "active": true },
  { "user": "fred",   "active": false }
];

_.every(users, { "user": "barney", "active": false });
// → false

_.some(users, ["active", false]);
// → true

什么?看不懂?

_.every => && 
_.some => ||

懂了吧。其实同样也算是对_.each的扩充。还有他们都有条件短路的优化哦。

Function _.curry

是函数柯里化的函数。不要问我为什么不是库里化。什么是柯里化自行百度。
例子:

let abc = function(a, b, c) {
  return [a, b, c];
};

let curried = _.curry(abc);

curried(1)(2)(3);
// → [1, 2, 3]

curried(1, 2)(3);
// → [1, 2, 3]

curried(1, 2, 3);
// → [1, 2, 3]

// Curried with placeholders.
curried(1)(_, 3)(2);
// → [1, 2, 3]

柯里化有3个常见作用:1. 参数复用;2. 构建高阶函数;3. 延迟计算。
参数复用的例子:

let parse = function(data, config){
    ……
    return ……;
};

let config = {};
let parseByConfig = _.curryRight(parse)(config);

如代码所示,这是一个数据解析函数,通过某些配置按照一定的规则去解析数据。如果在某个场景下参数配置都一样。那可以用柯里化先引入一个参数。然后再接收不同的数据。这样就不用在每次调用时都引入同样的config参数。

剩下两个特性一个等会讲,一个不在本文讨论范围内。

_.partial

部分函数,我习惯这么叫他,还是先看例子。

let greet = function(greeting, name) {
  return greeting + " " + name;
};

let sayHelloTo = _.partial(greet, "hello");
sayHelloTo("fred");
// → "hello fred"

// Partially applied with placeholders.
let greetFred = _.partial(greet, _, "fred");
greetFred("hi");
// → "hi fred"
let greet = function(greeting, name) {
  return greeting + " " + name;
};

let sayHelloTo = _.partial(greet, "hello");
sayHelloTo("fred");
// → "hello fred"

// Partially applied with placeholders.
let greetFred = _.partial(greet, _, "fred");
greetFred("hi");
// → "hi fred"

好像跟柯里化很像。是的,它其实就是柯里化的具体应用——构建高阶函数。_.curry会把一个函数转化成可以柯里化函数,而当这个柯里化函数接受了一定的参数后,它就变成了一个部分应用函数了。

Seq _.chain

这个是我认为的lodash中最有意思的方法。

$("div").css("color","red")
    .on("click", function(){})
    .fadeIn();

作为一个合格的前端攻城狮,你对这个一定不陌生。它一定给你带来过很多美好的记忆。那我们如何让这样一段优雅的代码应用到非DOM对象上呢。用_.chain就行了。

_.head(
   _.map(
    _.sortBy("users", "age"),
     function(o) {
       return `${o.user} is ${o.age}`;
     }
   )
 )

 _.chain(users)
  .sortBy("age")
  .map(function(o) {
    return o.user + " is " + o.age;
  })
  .head()
  .value();  

两段代码在做一样的事情。你更喜欢哪个呢。不过要注意_.chain最后的value。因为_.chain用一个容器包装了你的对象,最后需要通过value返回出真正的值。如果不能理解,联想一下下面这段代码:

$("div")[0].classList

用jQuery选择器筛选到的是jQuery对象,而如果要调用真正的DOM对象的属性的话,还要用索引去调用它。

Util _.flow
function square(n) {
  return n * n;
}

var addSquare = _.flow(_.add, square);
addSquare(1, 2);
// → 9

这同样是用来组合高阶函数的一个方法。如果用数学的角度去思考的话,就有点像, 把函数 f(), g(), 和h() 组合起来可以得到复合函数 f( g( h() ) )。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79387.html

相关文章

  • webpack入门学习手记(二)

    摘要:例如现在的入门学习手记系列。收到粉丝留言和打赏的喜悦。安装上一篇入门学习手记一,主要是介绍了的核心概念,是整个学习过程的基础知识。新生成的类似如下入门学习手记因为生成的内容过多,我直接省略掉了。 showImg(https://segmentfault.com/img/bVbk5Nd?w=1150&h=599); 本人微信公众号:前端修炼之路,欢迎关注。 最近开始想要维护一个个人的公众...

    Joyven 评论0 收藏0
  • Lodash常用API笔记

    摘要:中文文档目前我只找到了版本,现在已经更新到了,好多文档已经过期。而且中太多,有时候常用的几个我总是记不住名字,在这里贴出来,方便自己和大家。原生用法直接使用的根据条件去除某个元素。 lodash中文文档目前我只找到了3.10.x版本,现在lodash已经更新到4.17.x了,好多文档已经过期。而且lodash中api太多,有时候常用的几个我总是记不住名字,在这里贴出来,方便自己和大家。...

    Yujiaao 评论0 收藏0
  • Lodash学习笔记 - slice函数

    摘要:文档地址中文文档英文文档源码地址第一个函数是,不过源码中依赖了,所以第一篇文章就从开始。这个函数的作用就是裁剪数组,从下标开始,到下标结束,但是并不包含,并将结果作为一个数组返回。并且注明了这个方法用于代替来确保数组正确返回。 百忙之中(闲来无事)想抽点时间好好读一下源码,于是就选了Lodash来写一个系列罢。读源码顺序就按照loadsh文档顺序来。 文档地址:中文文档   英文文档源...

    lei___ 评论0 收藏0
  • Lodash学习笔记 - chunk函数

    摘要:文档地址中文文档英文文档源码地址将数组拆分成多个长度的区块,并将这些区块组成一个新数组。如果无法被分割成全部等长的区块,那么最后剩余的元素将组成一个区块。 百忙之中(闲来无事)想抽点时间好好读一下源码,于是就选了Lodash来写一个系列罢。读源码顺序就按照loadsh文档顺序来。 文档地址:中文文档   英文文档源码地址:gayhub _.chunk(array, [size...

    DrizzleX 评论0 收藏0
  • Lodash学习笔记 - compact函数

    摘要:文档地址中文文档英文文档源码地址创建一个新数组,包含原数组中所有的非假值元素。例如和都是被认为是假值。下面对比一下两者效率,如下图传送门可以看到使用更快,如果没有兼容性需求,还是使用原生函数比较好。 百忙之中(闲来无事)想抽点时间好好读一下源码,于是就选了Lodash来写一个系列罢。读源码顺序就按照loadsh文档顺序来。 文档地址:中文文档   英文文档源码地址:gayhub ...

    habren 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<