如何优雅的链式取值之 MayBe 函子

栏目: 编程语言 · 发布时间: 6年前

内容简介:本文基于如何优雅地链式取值可能有人之前看过我写的关于函数式编程的东西,也有人看过这一篇文章。由于我还是学生,开发经验相对较少,所以对于函数式编程如何应用存在一些疑惑。之前也问过面试官,说是实际开发中用的比较少,因为别人可能需要通读你的代码才能明白你写的东西。但是这篇文章就提供给了我一个很好的应用函数式编程的机会。从如何优雅地链式取值 这篇文章的描述中,可以看出处理嵌套层级特别深的代码经常会由于数据的原因而出一些错。例如下面呢这种数据

本文基于如何优雅地链式取值

可能有人之前看过我写的关于函数式编程的东西,也有人看过这一篇文章。由于我还是学生,开发经验相对较少,所以对于函数式编程如何应用存在一些疑惑。之前也问过面试官,说是实际开发中用的比较少,因为别人可能需要通读你的代码才能明白你写的东西。但是这篇文章就提供给了我一个很好的应用函数式编程的机会。

从如何优雅地链式取值 这篇文章的描述中,可以看出处理嵌套层级特别深的代码经常会由于数据的原因而出一些错。例如下面呢这种数据

const res = {
    data:{
        oneGoods:{
            lists:[{price: 1,name:'apple'}]
        },
        antherGoods:{
            lists:[{price: 2}]
        }
    }
}

复制代码

假设我们想对 oneGoods 里面的 lists 中的商品的 name 进行操作,我们可以这么写

res.data.oneGoods.lists[0].name.toUpperCase()
// APPLE
复制代码

那么问题就来了,假设 name 不存在呢,这就会报错,导致程序终止。例如

res.data.antherGoods.lists[0].name.toUpperCase()
// Cannot read property 'toUpperCase' of undefined
复制代码

或者再极端一点,lists 中没有那一项

res.data.antherGoods.lists[1].name.toUpperCase()
// Cannot read property 'name' of undefined
复制代码

有哪些方式那篇文章已经说的差不多了,但是有一种没有提到,就是使用函数式编程的 MayBe 函子。来看看用 MayBe 函子怎么做吧。

其实在函数式编程之函子 中已经说过了,这里再简单介绍一下吧。

const MayBe = function(val){
    this.val = val;
}

MayBe.of = function(val){
    return new MayBe(val);
}

MayBe.prototype.isNothing = function(){
    return this.val===undefined || this.val===null;
}

MayBe.prototype.map = function(fn){
    return this.isNothing() ? MayBe.of(null):MayBe.of(fn(this.val));
}
复制代码

首先函子是一个实现了 map 方法的普通对象。MayBe 能够保存任何传进来的值。MayBe.of 是一个静态方法,能够返回一个新的 MayBe 实例。然后它实现了 map 方法,在执行 map 方法时会调用 isNothing 方法进行判断,如果为 null 或者 undefined 就会返回一个值为 null 的对象。

那么用这个怎么处理之前的链式调用呢。

MayBe.of(res).map(res=>res.data)
             .map(data=>data.oneGoods)
             .map(oneGoods=>oneGoods.lists)
             .map(lists=>lists[0])
             .map(list=>list.name)
             .map(name=>name.toUpperCase())
// MayBe {val: "APPLE"}
MayBe.of(res).map(res=>res.data)
             .map(data=>data.antherGoods)
             .map(oneGoods=>oneGoods.lists)
             .map(lists=>lists[0]).map(list=>list.name)
             .map(name=>name.toUpperCase())
// MayBe {val: null}
MayBe.of(res).map(res=>res.data)
             .map(data=>data.antherGoods)
             .map(oneGoods=>oneGoods.lists)
             .map(lists=>lists[1])
             .map(list=>list.name)
             .map(name=>name.toUpperCase())
// MayBe {val: null}
复制代码

虽然看起来并不简单,其实逻辑比较简单,就是代码多了一点。但是这种链式调用的话类似于 promise,所以使用起来特别舒服,而且它把对于错误的处理抽象了出来,让我们无需关系这部分。所以也是一种很好的解决方案。

总归也找到了函数式编程的一种应用场景,不同的方案有不同的好处,多了解一些东西总能拓宽自己的思路吧。而且那篇文章没有提到可能是因为没有想到 MayBe 函子的应用场景,或者不太了解函数式编程,也算是对那篇文章的一个补充吧。希望能引起大家学习函数式编程的兴趣?


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Servlet与JSP核心编程

Servlet与JSP核心编程

(美国)霍尔等著、赵学良译 / 霍尔 / 清华大学出版社 / 2004-06-01 / 59.0

《Servlet与JSP核心编程》(第2版)叙述详尽,条理清晰。对于初学者来说是一本不可多得的入门书籍,经验丰富的Servelet和JSP开发人员也可以通过阅读《Servlet与JSP核心编程》(第2版)得到巩固和提高。一起来看看 《Servlet与JSP核心编程》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

随机密码生成器
随机密码生成器

多种字符组合密码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具