1. 首页

immutable操作(一) -这些点我们需要注意~

immutable 是什么?不变的、一成不变的。在 Javascript 中一般指一个变量在经过一个 function 处理之后,可以保持入参数据不变。

一、什么是 immutable?

作者简介:hustcc 蚂蚁金服·数据体验技术团队

举个真实日常例子:前两天,在业务代码中,需要获得数据的中位数,并使用 echarts 绘制出中位线,辅助分析。写代码之前,先找了一下中位线的定义。

对于有限的数集,可以通过把所有观察值高低排序后找出正中间的一个作为中位数。如果观察值有偶数个,通常取最中间的两个数值的平均值作为中位数。

哦,挺简单,于是奋笔疾书(其实是 github 上的代码片段

JS中文网 – 前端进阶资源教程 www.javascriptC.com
一个致力于帮助开发者用代码改变世界为使命的平台,每天都可以在这里找到技术世界的头条内容


/** * 求取数组中的中位数 * [1, 2, 3, 4, 4] -> 3 * [1, 2, 3, 4, 5, 6] -> 3.5 */ const calculateMedian(arr) => {  // 1. 排序  arr.sort((a, b) => a - b);  const half = Math.floor(arr.length / 2); // 2. 按照中位数定义计算  // 奇数长度则中间值,偶数长度则中间两个数的平均值  return arr.length % 2 !== 0 ? arr[half] : (arr[half - 1] + arr[half]) / 2.0; }

这段代码的问题在于函数是 mutable 的:

当经过函数 calculateMedian 求取数组 [5, 4, 3, 2, 1] 的中位数的时候,导致入参数组变成了 [1, 2, 3, 4, 5]。导致后续的代码拿到的数组,都是经过排序的,数据都是混乱的。

上述代码只需要修改一个地方即可:


const newArr = [].concat(arr).sort((a, b) => a - b);

其中 [].concat(arr) 达到的效果就是代码的 immutable。

通过这样的一个实际例子,我想应该很容易理解 mutable 代码造成的影响是什么?

  • 数据污染:经过一个方法,数据就变化了,多么可怕。
  • 数据不可控:数据不仅仅是被修改,而且我们没法控制数据被修改的规律。
  • debug 黑洞:一般的 bug,如果了解业务,可能不用 debugger 就能定位一二;mutable 产生的 bug,没办法,新增代码一句句 F10 吧。

二、常见的原因

很多情况下,道理我们都懂,但是还是会不经意写出 mutable 的代码。分为几种情况,看起来清晰一些吧!

1. 意识不清晰

很多开发者在写代码的时候,没有从全局胜寒意识到函数必须保证 immutable,只在乎自己的函数输入输出符合要求。

开发者需要有时刻警惕的意识,一旦涉及到 object 的操作,先提醒自己注意不可变。特别是对于公共模块的开发,开源项目的开发,养成“变道就打转向灯的好习惯”。

2. 函数理解不清晰

Array 常见的函数 push、pop、shift 等,一般都能理解它们是会修改原数组数据,是 mutable 的函数。

但是对于上述例子中的 sort 函数应该就是理解上容易产生歧义(自己之前一直以为是生成一个新的数组,写完这篇,我去搜索了整个业务代码)。同样的,容易产生歧义的函数包括:

  • sort
  • reverse
  • fill
  • splice
  • delete

注意:Array 中 immutable 函数很多,以上几个函数是功能上容易误解的。

3. 使用“不靠谱”的开源库

GitHub 真是个好东西,只要你能想到的代码,基本都有参考的,特别是 JavaScript 语言的。

但是你永远不知道你使用的轮子是不是仅仅是一个课堂作业练手的。在使用一个开源模块的时候,需要观察:

  • 单测是否完善:不是指单测是不是绿色(pass),而是看单测代码是否靠谱

在完善的单测可以看到:

  1. 项目实际的使用方式,这些很可能是 README 中无法完整写出来的东西。
  2. 理解项目的模块划分,组织架构。
  3. 开发者在项目代码中扣住的开发细节点。

比如,如果 immutable 是项目的一个重要特性之一,那么在单测代码中一定会反映出来。

  • npm 下载量

就像在网上购物一样,比较懒的购物者,直接买订单数最多的爆款。

  • issues

可以关注在 issue 处理速度、issue 中搜索关键字,可以大概知道是否存在这些问题。

  • 何妨 review 一下

如果代码简单,可以简单 review 一下,抓住代码实现的关键点。

三、如何写 immutable 的代码

既然要写 immutable 的代码,那我们应该怎么做?

1. 靠谱开源项目

  1. immutability-helper:基于原始 Array 和 Object 的 immutable 操作,很好用。
  2. js-joda:日期 Date immutable 方法。
  3. immutable-js:Facebook 的 immutable 模块,定义了新的数据结构,使用成本相对高一点点。
  4. immutability-helper-x:包装 immutable-helper,使用更友好。
  5. immu:基于 Proxy 的 immutable 模块,思路新颖,但是兼容性差一点。

2. 单测约束

针对开头的 calculateMedian 函数,写一个单测:


describe('calculateMedian', () => { test('immutable', () => {   const a = [5, 4, 3, 2, 1]; const aClone = a.slice(); expect(calculateMedian(a)).toBe(3); // 保证不能被修改! expect(a).toEqual(aClone);  }); });

单测约束之后,以后其他人修改这么代码导致 mutable 的时候,也会 ci 报错的,保证这个方法的长治久安。

除此之外,开启 Eslint 工具,也可以对 Object 的 mutable 自动告警。

3. 解构和 spread 语法

解构是 spread 语法是 ES6 中的新语法,也是我个人用的非常多的,一般代码的 immutable 写法,都可以满足。

  • Object 解构与 spread

比如我们有一个用户信息 A(几十项信息),然后需要创建一个用户信息 userB,除 id、name 不一样之外,其他都和 userA 一致。


const userA = { id: 1, name: 'hustcc', addr: 'Hangzhou', birth: '1992-08-01', // ...  // 很多的数据不列出了 }; // 结构和 spread 写法创建 userB const userB = { ...userA, id: 2, name: 'ProtoTeam', };
  • 数组 immutable 操作

const arr = [1, 2, 3, 4, 5]; // push 操作 const arrPush = [ ...arr, 6, ]; // shift 操作 const [e, ...arrShift] = arr; // concat const arrConcat = [...arr, ...arr];

四、最后

在 react + redux 技术栈下,不可变数据结构是大家都提倡的做法,所以又很多框架层面的东西帮我们处理了这些事情。

但是实际上,我们在平时的业务代码开发中,就需要有 immutable 的意识,善用 ES6 语法,就可以解决我们大部分的场景。

对我们团队感兴趣的可以关注专栏,关注github或者发送简历至’tao.qit####alibaba-inc.com’.replace(‘####’, ‘@’),欢迎有志之士加入~

原文地址:github.com/ProtoTeam/b…

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

本文来源于网络,其版权属原作者所有,如有侵权,请与小编联系,谢谢!

转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com

标题:immutable操作(一) -这些点我们需要注意~

链接:https://www.javascriptc.com/2176.html

原文链接:https://juejin.im/post/5aa8ae316fb9a028bd4c0202

« 浅析redux-saga实现原理
Immutable 操作(二) – 在 React 中的实践»
Flutter 中文教程资源

相关推荐

QR code