通过利用immutability的能力编写更安全和更整洁的代码

原文:Write safer and cleaner code by leveraging the power of “Immutability”

译者:neal1991

welcome to star my articles-translator, providing you advanced articles translation. Any suggestion, please issue or contact me

LICENSE: MIT

Immutability是函数式编程的重要基础之一。它允许你能编写更安全以及更整洁的代码。我将会通过一些JavaScript例子来向你展示如何来达到immutability。

根据维基百科:

不可变对象是一个在创建之后不能修改其状态的对象。这正与可变对象相反,它能够在创建之后被修改。在某些情况下,对象被认为是不可变的,即使其内部的某些属性发生改变,但是从外部的角度来看这个对象的状态看起来还是没有发生变化的。

Immutable数组

数组是理解immutability如何工作的很好的起点。让我们一起来看一看。

const arrayA = [1, 2, 3];
arrayA.push(4); const arrayB = arrayA;
arrayB.push(5); console.log(arrayA); // [1, 2, 3, 4, 5]
console.log(arrayB); // [1, 2, 3, 4, 5]

这个例子将arrayA的引用分配给arrayB,因此这个push方法在这两个变量中都会添加5这个值。我们的代码间接地修改其它的值,这并不是我们想要的。这也违反了immutability的原则。

我们可以通过使用 slice函数将我们的例子提升为immutable,并且这个代码的行为也产生了变化。

const arrayA = [1, 2, 3];
arrayA.push(4); const arrayB = arrayA.slice(0);
arrayB.push(5); console.log(arrayA); // [1, 2, 3, 4]
console.log(arrayB); // [1, 2, 3, 4, 5]

这正是我们想要的。代码没有改变其它值。

提醒:当你使用 push 向数组添加一个值的时候,你是在改变这个数组。你想要避免修改变量,因为这可能会给你的代码带来负面影响。 slice函数能够返回数组的拷贝。

函数

现在你知道如何避免修改其它值。那么你知道如何写“纯”函数了嘛?纯函数是对于一个不会又任何副作用以及不会改变状态的函数另一个称呼。

我们来看一个利用数组示例中相同原理的函数。 首先,我们创建一个改变其它值的函数,然后我们将该函数改进为“纯”。

const add = (arrayInput, value) => {
arrayInput.push(value); return arrayInput;
};
const array = [1, 2, 3]; console.log(add(array, 4)); // [1, 2, 3, 4]
console.log(add(array, 5)); // [1, 2, 3, 4, 5]

因此再一次,我们修改我们的输入,这会产生一个无法预测的函数。在函数式编程的世界中,对于函数有一个黄金法则:使用相同输入的函数应该返回相同的结果。

上述的函数违反了这一黄金法则。每一次我们的add函数被调用的时候,它就会修改这个array变量,结果也就不同了。

让我们一起看看看如何改变我们add函数的事先,因此让其成为immutable。

const add = (arrayInput, value) => {
const copiedArray = arrayInput.slice(0);
copiedArray.push(value); return copiedArray;
}; const array = [1, 2, 3];
const resultA = add(array, 4);
console.log(resultA); // [1, 2, 3, 4]
const resultB = add(array, 5);
console.log(resultB); // [1, 2, 3, 5]

现在我们可以调用我们的函数多次,并且可以预期在相同输入的时候,输出都是相同的。这是因为我们不再会修改这个array变量。我们能够将这个函数成为“纯函数”。

注意:你也能使用concat,而不是slice以及push

因此:arrayInput.concat(value)

我们能够利用ES6中的[扩展语法]((https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Operators/Spread_operator)来缩短函数。

const add = (arrayInput, value) => […arrayInput, value];

并发

NodeJS应用使用了一个叫做并发的概念。一个并发操作意味着两个计算能够能够同时进行并且不用考虑另外一个。如果这里有两个线程的话,第二个计算不需要等到第一个计算完成才能只需执行。

NodeJS通过event-loop让并发变得可能。event-loop会重复获取一个事件,并且每次会激活任一一个事件处理器来监听事件。这个模型允许NodeJS应用处理大量的请求。如果你想了解更多,阅读这篇关于event-loop的文章

Immutability和并发之间有什么关系呢?因为做个操作能够在函数的作用域外以并发的方式改变值,这会产生一个不可靠的输出以及无法预期的结果。意识到函数可能会在作用域外修改变量,因此这可能会非常危险的。

下一步

Immutability对于你理解和学习函数式编程是非常重要的一个概念。你可能希望了解mmutableJS](https://facebook.github.io/immutable-js),其由Facebook开发者编写。这个library提供了某些不可变的数据机构,比如 Map, Set以及List.

[Immutable.js, persistent data structures and structural sharing](Immutable.js, persistent data structures and structural sharing)(译者注:墙外地址)

通过利用immutability的能力编写更安全和更整洁的代码的更多相关文章

  1. 利用 Django REST framework 编写 RESTful API

    利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framewor ...

  2. 利用Warensoft Stock Service编写高频交易软件

    利用Warensoft Stock Service编写高频交易软件 无论是哪种交易软件,对于程序员来讲,最麻烦的就是去实现各种算法.本文以SAR算法的实现过程为例,为大家说明如何使用Warensoft ...

  3. 利用Warensoft Stock Service编写高频交易软件--DEMO

    利用Warensoft Stock Service编写高频交易软件 无论是哪种交易软件,对于程序员来讲,最麻烦的就是去实现各种算法.本文以SAR算法的实现过程为例,为大家说明如何使用Warensoft ...

  4. 第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码

    第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码 scrapy-redis是一个可以scrapy结合redis搭建分布式爬虫的开 ...

  5. C++:利用如下公式,编写函数计算∏的值,直到最后一项的绝对值小于e,主程序接收从键盘输入的e,输出∏的值(保留5位小数)。 ∏/4 = 1-1/3+1/5-1/7...

    利用如下公式,编写函数计算∏的值,直到最后一项的绝对值小于e,主程序接收从键盘输入的e,输出∏的值(保留5位小数). ∏/4 = 1-1/3+1/5-1/7... #include <iostr ...

  6. 阿里云MVP:开发者的超能力,用技术创造更好世界

    阿里云MVP:开发者的超能力,用技术创造更好世界 2019年3月,第8期阿里云MVP(最有价值专家)完成终审,截至目前,全球已有27个国家和地区.近500位云计算专家和优秀开发者成为阿里云MVP.阿里 ...

  7. iOS书摘之编写高质量iOS与OS X代码的52个有效方法

    来自<Effective Objective-C 2.0编写高质量iOS与OS X代码的52个有效方法>一书的摘要总结 一.熟悉Objective-C 了解Objective-C语言的起源 ...

  8. 专访|HPE测试中心总监徐盛:测试新思维-DevOps,持续测试,更敏捷,更快速

    2016年7月22日,「HPE&msup软件技术开放日」将在上海浦东新区,张江高科技园区纳贤路799号科荣大厦小楼2楼举办,msup携手HPE揭秘全球测试中心背后的12条技术实践. 徐盛:HP ...

  9. 第一章 熟悉Objective -C 编写高质量iOS与OS X代码的52 个有效方法

    第一章 熟悉Objective -C   编写高质量iOS与OS  X代码的52 个有效方法   第一条: 了解Objective-C 语言的起源 关键区别在于 :使用消息结构的语言,其运行时所应执行 ...

随机推荐

  1. 14 Spring Boot Shiro限制登录尝试次数

  2. MySQL把多条数据给汇总成一条数据

    用到的是这个函数: group_concat() select group_buying_id, group_concat(app_user_ids) from org_user_group grou ...

  3. ViewContainerRef 动态创建视图

    Angular DOM 操作 相关的APIs和类: 查询DOM节点 template variable ref: 模版变量引用,相当于react中的ref ViewChild: 查询DOM,返回单个元 ...

  4. Acitiviti的查询及删除(六)

    流程定义查询 查询部署的流程定义. /** * 查询流程定义信息 //act_re_procdef */ public class QueryProcessDefinition { public st ...

  5. python 获取某个文件下的所有文件

    import os files = os.listdir(load_Graph_file_path) cnt = 0 for file in files: print(file) if (os.pat ...

  6. [CSP-S模拟测试]:木板(数学)

    题目传送门(内部题68) 输入格式 输入有若干行,每行一个整数$N$,以$0$结束 输出格式 每行一个整数表示方案数,方案不同当且仅当$E$.$F$.$G$的坐标不同 样例 样例输入: 1020100 ...

  7. IDEA简单破解激活操作流程(我在用的)

    其实简单的,你需要下一个包,将他放入你的IDEA安装目录的bin下,如下下图 下载地址:https://pan.baidu.com/s/1aJDefDGmfYGrkcJCpZYccA 看到红线的地方了 ...

  8. 爬虫 ---- BeautifulSoup的基础使用

    #BeautifulSoup的基础使用from bs4 import BeautifulSoup #导入bs4库 html = "<p class='stylecss'>< ...

  9. vmware 虚拟 CPU 性能计数器事件与主机 CPU 不兼容。

    错误提示:虚拟 CPU 性能计数器事件与主机 CPU 不兼容. 点放弃 如果是暂时状态选关机, 丢失掉运行状态,即可保留硬盘内容重新开机

  10. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_07 缓冲流_2_BufferedOutputStream_字节缓冲

    子类 继承父类,这些方法都可以使用 必须写上flush,刷新数据数据才能写入到文件内