通过利用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 语言的起源 关键区别在于 :使用消息结构的语言,其运行时所应执行 ...
随机推荐
- 02-webpack的作用
webpack的作用,将不同静态资源的类型打包成一个JS文件,在html页面应用该JS文件的时候,JS文件里的html就可以正常的运行,去执行操作. 也可以加载前端页面的CSS样式.Img图片
- echart--如何自定义提示框的内容和样式实例
图例的大概样子 具体设置代码为:
- 文本跟随鼠标并且显示x轴和y轴位置
一.文本跟随鼠标并且显示x轴和y轴位置 代码如下: window.onload=function(){ var mydiv = document.createElement("div&quo ...
- 20180827-Java网络编程
Java 网络编程 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java.net包中J2SE的API包含有类和接口,它们提供低层次的通信细节.你可以直接使用这些类和接 ...
- 「LibreOJ β Round #2」计算几何瞎暴力
https://loj.ac/problem/517 题解 首先我们如果没有排序这个骚操作的话,可以直接记一下各个数位的前缀和,然后异或标记给全局打,查询的时候先把区间信息提取出来然后整体异或就好了. ...
- Springboot-H2DB
为什么在Springboot中用H2DB 用Springboot开发需要连接数据库的程序的时候,使用H2DB作为内存数据库可以很方便的调试程序. 怎么用 1.加入依赖 <dependency&g ...
- python安装使用(windows)
安装 参考:http://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/install.html#scrapy 用到的文件:https://share.weiy ...
- node+express 发送get请求
var express = require('express') , app = express(); var querystring = require('querystring'); var ut ...
- linux下安装nginx(nginx(nginx-1.8.0.tar.gz),openssl(openssl-fips-2.0.9.tar.gz) ,zlib(zlib-1.2.11.tar.gz),pcre(pcre-8.39.tar.gz))
:要按顺序安装: 1:先检查是否安装 gcc ,没有先安装:通过yum install gcc-c++完成安 2:openssl : tar -zxf openssl-fips-2.0.9.tar. ...
- glibc升级,解决glib版本过低的问题
Debian wheezy下的glibc版本为2.13,安装几个软件都运行不了,报以下类似错误:xxxx: /lib/i386-linux-gnu/i686/cmov/libc.so.6: versi ...