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

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

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

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

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

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

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 函子的应用场景,或者不太了解函数式编程,也算是对那篇文章的一个补充吧。希望能引起大家学习函数式编程的兴趣?


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

查看所有标签

猜你喜欢:

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

算法笔记

算法笔记

胡凡、曾磊 / 机械工业出版社 / 2016-7 / 65

这是一本零基础就能读懂的算法书籍,读者不需要因为自己没有语言基础而畏惧。书籍的第2章便是一个C语言的入门教程,内容非常易懂,并且十分实用,阅读完这章就可以对本书需要的C语言基础有一个较好的掌握。 本书已经覆盖了大部分基础经典算法,不仅可以作为考研机试和PAT的学习教材,对其他的一些算法考试(例如CCF的CSP考试)或者考研初试的数据结构科目的学习和理解也很有帮助,甚至仅仅想学习经典算法的读者......一起来看看 《算法笔记》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具