通过利用immutability的能力编写更安全和更整洁的代码
通过利用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的能力编写更安全和更整洁的代码的更多相关文章
- 利用 Django REST framework 编写 RESTful API
利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framewor ...
- 利用Warensoft Stock Service编写高频交易软件
利用Warensoft Stock Service编写高频交易软件 无论是哪种交易软件,对于程序员来讲,最麻烦的就是去实现各种算法.本文以SAR算法的实现过程为例,为大家说明如何使用Warensoft ...
- 利用Warensoft Stock Service编写高频交易软件--DEMO
利用Warensoft Stock Service编写高频交易软件 无论是哪种交易软件,对于程序员来讲,最麻烦的就是去实现各种算法.本文以SAR算法的实现过程为例,为大家说明如何使用Warensoft ...
- 第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码
第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码 scrapy-redis是一个可以scrapy结合redis搭建分布式爬虫的开 ...
- 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 ...
- 阿里云MVP:开发者的超能力,用技术创造更好世界
阿里云MVP:开发者的超能力,用技术创造更好世界 2019年3月,第8期阿里云MVP(最有价值专家)完成终审,截至目前,全球已有27个国家和地区.近500位云计算专家和优秀开发者成为阿里云MVP.阿里 ...
- iOS书摘之编写高质量iOS与OS X代码的52个有效方法
来自<Effective Objective-C 2.0编写高质量iOS与OS X代码的52个有效方法>一书的摘要总结 一.熟悉Objective-C 了解Objective-C语言的起源 ...
- 专访|HPE测试中心总监徐盛:测试新思维-DevOps,持续测试,更敏捷,更快速
2016年7月22日,「HPE&msup软件技术开放日」将在上海浦东新区,张江高科技园区纳贤路799号科荣大厦小楼2楼举办,msup携手HPE揭秘全球测试中心背后的12条技术实践. 徐盛:HP ...
- 第一章 熟悉Objective -C 编写高质量iOS与OS X代码的52 个有效方法
第一章 熟悉Objective -C 编写高质量iOS与OS X代码的52 个有效方法 第一条: 了解Objective-C 语言的起源 关键区别在于 :使用消息结构的语言,其运行时所应执行 ...
随机推荐
- 面试题常考&必考之--js闭包特性和优缺点 (外加小例子)
当内部函数被返回到外部并保存时,一定会产生闭包.闭包会产生原来的作用域链,不释放. 闭包,可以理解为,写一个函数,然后产生闭包的这种现象. 概念: 基础: 主要是:add reduce 被返回 ...
- qs的两个用途
qs是npm安装的库 1.qs.stringify() 将对象序列化成URL的形式,以&进行拼接 const Qs = require('qs'); let obj= { method: ...
- django FBV +CBV 视图处理方式总结
1.FBV(function base views) 在视图里使用函数处理请求. url: re_path('fbv', views.fbv), # url(r'^fbv' ...
- CG-CTF | 综合题
开场就是一个js混淆,直接丢到console里面 然后根据tip查头: 看到这个tip,一开始还以为要考注入了,用访问历史来进行注入,后来发现是我高估这题了,,,:
- [CSP-S模拟测试]:辣鸡(ljh) (暴力)
题目描述 辣鸡$ljh\ NOI$之后就退役了,然后就滚去学文化课了.然而在上化学课的时候,数学和化学都不好的$ljh$却被一道简单题难住了,受到了大佬的嘲笑.题目描述是这样的:在一个二维平面上有一层 ...
- 阿里云配置通用服务的坑 ssh: connect to host 47.103.101.102 port 22: Connection refused
1.~ wjw$ ssh root@47.103.101.102 ssh: connect to host 47.103.101.102 port 22: Connection refused ssh ...
- 源码编译安装Apache/2.4.37-------踩了无数坑,重装了十几次服务器才会的,不容易啊!
1.先进入/usr/local/中创建三个文件夹 apr apr-util apache cd /usr/local目录 mkdir apr mkdir apr-util mkdir apache 2 ...
- JS - 事件循环和任务队列
栈.堆和队列 栈:函数调用形成栈 堆:对象的内容分配在堆中 队列:一个 JavaScript 运行时包含了一个待处理的消息队列.在事件循环期间依次处理队列中的消息 事件循环 之所以称之为事件循环,是因 ...
- 在mpvue或者Vue中使用VUEX
第一个页面Index,主页哦 import Vue from'vue' import Vuex from'vuex' import getters from'./getters' import sta ...
- 像计算机科学家一样思考python-第4章 案例研究:接口设计
系统环境 ubuntu18 4.1turtle模块 模块一开始导入turtle模块就报错了 Python ( , ::) [GCC ] on linux Type "help", ...