作者:首席填坑官∙苏南
公众号:honeyBadger8
,群:912594095,本文原创,著作权归作者所有,转载请注明原链接及出处。
引言
之前项目中遇到数据拷贝、引用之间数据层级嵌套过深,拷贝的值相互之间影响的问题,后来引入了immutability-helper
,使用过程中的一些总结,跟大家分享下,至于为什么不是immutable
,请看下文分解,这里是@IT·平头哥联盟,我是首席填坑官
——苏南。
相信大家在面试/工作中都遇到过js对象/数组的拷贝问题,面试官问你,你一般怎么做??在现在ES6盛行的当下,不会一点ES6都不好意思说自己是前端(其实我一般都说自己是攻城狮、切图崽?),我们想的大多第一想法,如下:
Object.assign
- 最方便;[...]
- 最有逼格;JSON.parse
、JSON.stringify
- 完美组合;$.extend()
- jQuery时代的引领潮流时尚前沿的API;- 最后想到的才是自己递归实现一个;
但是通常我们使用的Object.assign
属于浅拷贝,当数据嵌套层级较深时,就……呵呵了;而JSON.parse、stringify
它应该是创建一个临时可能很大的字符串,然后又访问解析器,性能是比较慢的。于是后来发现了 immutable
「不可变数据」,曾经我也一度特别喜欢它,但时间久了,慢慢发现,它过于有个性了些、凡事都都没有任何商量的余地,所有的数据,从创建、变更、插入、删除等操作,都要按它的套路来,对于我这种一生放荡不羁爱自由的人来说,长时间的约束,是不能忍的;都说两人如果三观不合,是无法长久下去的,可能也是缘份吧,在后来的某一天偶然的闲逛中邂逅了新欢 ————Immutability Helpers。
嗯,今天的主题就是给大家分享一下,Immutability Helpers
的一些用法,会介绍API的使用操作和小技巧,如有不理解不对,请纠正:
太兴奋了,差点忘了,补充一下,一个简单的拷贝:
//实现一个简单的递归数据拷贝
let customClone = (rawObj)=>{
let copyObj = {
};
for (var key in rawObj) {
if( typeof rawObj[key] === 'object' && Object.prototype.toString.call(rawObj[key]) !== '[object Array]'){
copyObj[key] = customClone(rawObj[key]);
}else{
copyObj[key] = rawObj[key];
};
};
return copyObj;
};
let objA = {
"name":"苏南","sex":"男","height":"176"};
let objB = customClone(objA);
objB.signature = "宝剑锋从磨砺出,梅花香自苦寒来,做有温度的攻城狮";
console.log(objA);
console.log(objB);
- 补充一个
Object.assign
的坑 :
let data = {
a:1,
b:2,
children:{
name:"苏南",
organization:"@IT·平头哥联盟",
job:"首席填坑官",
address:"ShenZhen",
age:18
}
};
let data2 = Object.assign({},data);
data2.children.age = 28;
data2.children.job = "首席甩锅官";
data2.b = 666;
console.log("我是原始数据 data:",data);
console.log("我是复制后的数据 data2:",data2);
immutable 最后的一次回顾
都说有了新欢,忘了旧爱,但我不是那种无情无义的人,最后正式介绍一下 immutable
,为我俩的……画上一个圆满的句号:
再次强调,并不是觉得immutable
不好,不够强大,只是自己个人观点,有些不喜欢而已,各位immutable
粉勿喷,想了解更多的同学可以点击这里
Immutable data encourages pure functions (data-in, data-out) and lends itself to much simpler application development and enabling techniques from functional programming such as lazy evaluation.
使用示例:
const list1 = List([ 1, 2, 3 ]);
const list2 = List([ 4, 5, 6 ]);
const array = [ 7, 8, 9 ];
const list3 = list1.concat(list2, array);
console.log(list3) // List {size: 9, _origin: 0, _capacity: 9, _level: 5, _root: null, …} 是不能直接获取到数据的,须使用get,-- list3.get(0)
let data = fromJS({
obj:{
}
});
let data1 = {
a:1,
b:2,
children:{
name:"苏南",
}
};
let data2 = data.mergeIn(['obj'],data1,{
c:666});
console