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


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

查看所有标签

猜你喜欢:

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

Python Machine Learning

Python Machine Learning

Sebastian Raschka / Packt Publishing - ebooks Account / 2015-9 / USD 44.99

About This Book Leverage Python' s most powerful open-source libraries for deep learning, data wrangling, and data visualization Learn effective strategies and best practices to improve and opti......一起来看看 《Python Machine Learning》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具