javascript基础修炼(8)——指向FP世界的箭头函数 (4)

javascript中的对象很强大也很灵活,可并不是所有的场景中我们都需要这种灵活性。来看这样一个例子:

let a = { name:'tony' } let b = a; modify(b); console.log(a.name);

我们无法确定上面的输出结果,因为a和b这两个标识符指向了堆中的相同的地址,可外界无法知道在modify函数中是否对b的属性做出了修改。有些场景中为了使得逻辑过程更加可靠,我们不希望后续的操作和处理对最原始的数据造成影响,这个时候我们很确定需要拿到一个数据集的复制(比如拿到表格的总数据,在实现某些过滤功能的时候,通常需要留存一个表格数据的备份,以便取消过滤时可以恢复原貌),这就引出了老生常谈的深拷贝和浅拷贝的话题。

【深拷贝】是一种典型的防御性编程,因为在浅拷贝的机制下,修改对象属性的时候会影响到所有指向它的标识符,从而造成不可预测的结果。

在javascript中,常见的深拷贝都是通过递归来实现的,然后利用语言特性做出一些代码层面的优化,例如各个第三方库中的extend( )方法或者deepClone( )。可是当一个结构很深或者复杂度很高时,深拷贝的耗时就会大幅增加,有的时候我们关注的可能只是数据结构中的一部分,也就是说新老对象中很大一部分数据是一致的,可以共享的,但深拷贝过程中忽视了这种情况而简单粗暴地对整个对象进行递归遍历和克隆。

事实上【深拷贝】并不是防御性编程的唯一方法,Facebook的Immutable.js就用不可变数据的思路来解决这个问题,它将对象这种引用值变得更像原始值(javascript中的原始值创建后是不能修改的)。

//Immutable.js官网示例 var map1 = Immutable.Map({ a: 1, b: 2, c: 3 }); var map2 = map1.set('b', 50); map1.get('b'); // 2 map2.get('b'); // 50

你可以查看【Immutable.js官方文档】来了解如何使用它,通常它是结合React全家桶一起使用的。如果你对其实现原理感兴趣,可以查看《深入探究Immutable.js的实现机制》一文或者查看其他资料,来了解一下Hash树Trie树是如何作为Immutable的算法基础而被应用的。

当标识符指向不变的数据,当函数没有副作用,就可以大胆广泛地使用函数式编程了

四. 前端的学习路线

javascript基础

如果你能够很清楚高阶函数,柯里化,反柯里化这些关键词的含义和一般用途,并且至少了解Array的map和reduce方法做了什么事情,那么就可以进行下一步。否则就需要好好复习一下javascript的基础知识。在javascript中进行函数式编程会反复涉及到这些基本技术的运用。

《javascript函数式编程指南》

地址:https://llh911001.gitbooks.io/mostly-adequate-guide-chinese/content/

这是一本来自于gitbook的翻译版的非常棒的开源电子书,这本书很棒,但是如果将函数式编程的相关知识分为初中高级的话,这本书似乎只涵盖了初级和高级,而省略了中级的部分,当内容涉及到范畴论和代数结构的时候,理解难度会突然一下变得很大。当你读不懂的时候可以先停下来,用下一个资料进行过渡,然后回过头来再继续阅读后续的部分。

同时提一句,翻译者@胡子大哈也是之前提及的那本著名的《React小书》的主要作者。

Ramda.js官网博文集

地址:https://ramdajs.com/

Ramda.js为javascript提供了一系列函数式编程的工具函数,但官网的《Thinking In Ramda》系列教程,是非常好的中级教程,结合Ramda的API进行讲解,让开发者更容易理解函数式编程,它正好弥补了前一个资料中没有中级教程的问题。

Ramda.js的API

不得不说很多前端开发者都是从API开始学习函数式编程的,但很快就会发现学了和没学差不多,因为没有理论基础,你很难知道该去使用它。就好像给了你最顶尖的工具,你也没法一次性就做出好吃的牛排,因为你不会做。

Rx.js和Immutable.js

事实上笔者自己也还没有进行到这个阶段的学习,Rx.js是隶属于Angular全家桶的,Immutable.js是隶属于React全家桶的,即使在自己目前的工作中没有直接使用到,你也应该了解它们。

代数结构的理论基础

地址:https://github.com/fantasyland/fantasy-land

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfxpp.html