深拷贝和浅拷贝之 Immutable

  • 深拷贝是拷贝数据的值, 浅拷贝是拷贝数据的地址.
  • 值传递和引用传递.
值传递:
	var a = 10;
	var b = a;
	b += 20 ;
	console.log(a,b) // 10 30
引用传递: 
	var arr = [10,20,30,40];
	var newArr = arr;
	newArr[0] = 100;
	console.log(arr,newArr) // [100,20,30,40] [100,20,30,40]
  • 深拷贝
    • JSON.parse JSON.stringify 缺点 : 方法无法被拷贝
    • jquery方法: $extend( )** : 第一个值为true 就是深拷贝( 如果第一个值不填就浅拷贝 ) 第二个是 目标对象, 第三个是 需要合并的对像… 缺点 : React 引用jquery 不合适
var obj = {a:{name:'张三'}};
var newObj = $.extend(true,{},obj)
newObj.a.name = '李四'
console.log(newObj,obj)  // newObj{a:{name:李四}} 
// obj{a:{name:'张三'} 深拷贝原数据不会改变
  • Immutable.js 对 React 特别友好,提高了React的性能
Immutable 简介
  • immutable Data 就是一旦创建,就不能被更改的数据,对immutable 对象的任何修改或添加删除操作都会返回一个新的immutable对象, immutable 实现的原理是 Persistent Data Structure(持久化数据结构), 也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变,同时为了避免 deepCopy把所有节点都复制一遍带来的性能损耗
  • 在js,引用类型的数据,优点在于频繁的操作数据都是在原对象的基础上修改,不会创建新对象,从而可以有效的利用内存,不会浪费内存, 这种特性称为 mutable(可变),但恰恰它的优点也是它的缺点,太过于灵活多变在复杂数据的场景下也造成了它的不可控性, 假设一个对象在多处用到,在某一处不小心修改了数据,其他地方很难遇见到数据是如何改变的,针对这种问题的解决方法,一般就像刚才的例子,会想复制一个新对象,再新对象上做修改, 这无疑会造成更多的性能问题以及内存浪费.
    为了解决这种问题, 出现了 immutable对象,每次修改immutable对象都会创建一个新的不可变对象, 而老的对象不会改变
Immutable注意的地方

1.约定变量命名规则: 如所有immutable 类型对象以$$ 开头
2.fromJS和toJS会深度转换数据, 随之带来的开销较大,尽可能避免使用,单层数据转换使用Map() 和 List()
3.js是弱类型,但Map类型的key必须是string

Immutable 的一些api方法
const Immutable = require('immutable')
// console.log(Immutable)

//? Immutable 对数据的 增删改查 都会有一个返回值, 返回值是一个新的 Immutable
//? 最常见的数据结构  Map(obj)  List(arr)  Set Seq  用的最多的是前两种 不是原生es6


//* 如何将Immutable对象转换成原生js对象
//? 把Immutable数据结构转换成对象
// const map = Immutable.Map({a:1,b:2,c:3}).toJS();
// console.log(map)  // 变成对象了 { a: 1, b: 2, c: 3 }

// const list = Immutable.List([1,2,3,4]).toJS();
// console.log(list)  //? 转换成数组 [ 1, 2, 3, 4 ]


// const map = Immutable.Map({a:1,b:2,c:3,d:{name:'张三'}}).toJS();
// console.log(JSON.stringify(map))  // {"a":1,"b":2,"c":3,"d":{"name":"张三"}}


//! 深层次转换 比较耗费性能
// const map = Immutable.Map({a:1,b:2,c:3,d:{name:'张三'}}).toJS();
// const list = Immutable.List([1,2,3,4,["a","b",'c']]).toJS();
// console.log(map,list)  // { a: 1, b: 2, c: 3, d: { name: '张三' } } [ 1, 2, 3, 4, [ 'a', 'b', 'c' ] ]


//* 如何将原生js对象转换成Immutable对象
// const obj = {
//     a:1,
//     b:2
// }
// console.log(Immutable.fromJS(obj)) // 转换成Map 类型了

// const arr = [1,2,3,4]
// console.log(Immutable.fromJS(arr)) // 转换成了List 类型了

// //! 深层次转换 比较耗费性能
// const obj = {
//     a:1,
//     b:2,
//     arr:[1,2,3,4]
// }
// const arr = [1,2,3,4,{name:'张三'}]
// console.log(Immutable.fromJS(obj),Immutable.fromJS(arr)) // 转换成Map 类型了 转换成了List 类型了

//? 对象形式的 Map
// let map = Immutable.Map({a:1,b:2})
// console.log(JSON.stringify(map))

//? 数组形式的 List
// let list = Immutable.List([1,2,3,4])
// console.log(JSON.stringify(list))


//? 进行修改设置(1) setIn 方式
// const map1 = Immutable.Map({a:1,b:2,c:{name:'abc'}})
// 修改哪个值? 后面是修改成功的值
// const map2 = map1.setIn(["a"],'哈哈')
// const map2 = map1.setIn(["c","name"],'哈哈')
//? map1 不等于 map2  false 他们不是同一块内存里的
// console.log(JSON.stringify(map1))  // map1 数据是没有发生改变 {"a":1,"b":2}
// console.log(JSON.stringify(map2))  // map2 数据发生了改变  {"a":"哈哈","b":2}


//? 进行修改设置(2)  set方式
// const map1 = Immutable.Map({a:1,b:2})
// const map2 = map1.set('a','呵呵')

// console.log(JSON.stringify(map1))  // map1 数据是没有发生改变 {"a":1,"b":2}
// console.log(JSON.stringify(map2))  // map2 数据发生了改变  {"a":"呵呵","b":2}



//? 获取
// const map1 = Immutable.Map({a:1,b:2});
// const data = map1.get("a")
// console.log(data)

// const map1 = Immutable.Map({a:1,b:2,c:{name:'张三'}});
// const data = map1.getIn(['c','name'])
// console.log(data)

//? 删除 
// const map1 = Immutable.Map({a:1,b:2,c:{name:'张三'}});
// const newmap =  map1.delete('a')
// console.log(JSON.stringify(newmap))

// const newmap = map1.deleteIn(['c'])
// const newmap = map1.deleteIn(['c','name'])
// console.log(JSON.stringify(newmap))


//? 跟新 如果需要跟新 后面是一个函数  必须要返回一个数据 return
// const map1 = Immutable.Map({a:1,b:2,c:{name:'张三'}});
// const map2 = map1.update('a', (val)=>val+=2);
// console.log(JSON.stringify(map2))  // {"a":3,"b":2,"c":{"name":"张三"}}

// const map2 = map1.updateIn(['c','name'], (val)=>val+=2);  // {"a":1,"b":2,"c":{"name":"张三2"}}
// console.log(JSON.stringify(map2)) 

//? 对象合并 覆盖
// const map1 = Immutable.Map({a:1,b:2,c:{name:'张三'}});
// const map2 = Immutable.Map({a:6,b:10,d:{name:'李四'}});
//? 只要遇到相同的东西就会被覆盖, 后者覆盖前者 map2 覆盖 map1
// const map3 = map1.merge(map2)
// console.log(JSON.stringify(map3))  // {"a":1,"b":2,"d":{"name":"李四"},"c":{"name":"张三"}}


//? 判断两个数据结构是否相等
// const map1 = Immutable.Map({a:1,b:2,c:{name:'张三'}});
// const map2 = Immutable.Map({a:6,b:10,d:{name:'李四'}});
// console.log(map1.equals(map2)); // 每次返回是新的Immutable 所以不相等 false


//? 数据结构的操作
// const list = Immutable.List([1,2,3,4]);
// const list2 = list.push(10)  //? 添加
// console.log(list2) // [ 1, 2, 3, 4, 10 ],

// const list3 = list2.pop();  //? 删除
// console.log(list3)  // [ 1, 2, 3, 4 ]

//? 合并数组
// const list = Immutable.List([1,2,3,4]);
// const newlist = Immutable.List([10,20,30,4]);
// const list4 = list.concat(newlist)  //? 合并数组
// console.log(list4) // 合并里面数是不会被覆盖 [ 1,  2,  3, 4, 10, 20, 30, 4 ]


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值