这个“不可变数据”并不是不能修改,它是是指一旦生成就不能再修改的数据,这类数据的修改操作会返回一个新的数据,而原来的数据结构保存的内容不会发生变化。
在获取不可变数据的时候,就不得不说克隆了,克隆有两种方式:深克隆和浅克隆
浅克隆,在复制数据的构成中,不会对数据结构做递归操作。而是为基本数据类型的值复制备份,而引用数据类型的值,仅仅是复制一份引用备份,并且指向内存中的同一个地址。
当我们通过新数据访问到引用数据类型,并且进行操作后,源数据的同一个引用的值也会受到影响。
浅克隆示意图:

深克隆,就是能够生成一个完全独立的数据。但是它也有一些缺点,比如占用空间大、性能更差,因为它是通过递归遍历引用数据类型的数据。
如果数据结构中存在循环引用,或者是属性之间相互引用时候,这时只通过简单的数据类型判断,可能无得到真正的深克隆数据。
那么一个稳定的深克隆方法是比较复杂的。
但是我们通过现成的工具直接借用深克隆的函数,把比如lodash.js的cloneDeep()方法,
获取不可变数据另一个方法,就是Immutable,Immutable也是提供了很多的数据处理函数,函数的命名和使用方法,和Lodash基本上一直,上手很快。
const {Map} = require('immutable')
const obj = { name: "duxin", count: 100, data: { name: 'qingzhu', ttt: '097' } }
let map1 = Map(obj);
map1 = map1.set('name', 'Duxinyues');
map1 = map1.set('count', '000000');
map1 = map1.set('data', {name:'QINGZHUYUE',count:'======'});
console.log(map1.get('name'),map1.get('count'),map1.get('data')) // Duxinyues 000000 { name: 'QINGZHUYUE', count: '======' }
console.log(obj)// { name: 'duxin', count: 100, data: { name: 'qingzhu', ttt: '097' } }
在这段代码中,是将obj复制备份并且转化为Map结构,当我们在修改map1的时候,并不会影响到obj的值。
但是在实际应用中,如果源数据是一个对象,那么在复制备份转化为Map,在进行修改,最后还需还原为对象
console.log(map1.toObject()) //{ name: 'Duxinyues',count: '000000', data: { name: 'QINGZHUYUE', count: '======' }}

如上图所示,immutable提供了很多的数据结构和方法,比如isMap,判断一个数据是否是Map结构:例如,需要判断上面代码片段中的obj变量,是不是Map结构
console.log(Map.isMap(obj))
在实际的应用场景中,根据自己的需求选择合适技术!