企业设计网站公司有哪些,做国际网站的流程,厦门市建设路网站,创意作品设计方案大全Immutable-js 这个库的实现是深拷贝还是浅拷贝#xff1f;immutable 来源immutable.js三大特性#xff1a; 持久化数据结构结构共享惰性操作 Immutable.js 的几种数据类型 immutable 使用 使用 npm 安装 immutable#xff1a; 常用API介绍 MapListList.isList() 和 Map.isMa…Immutable-js 这个库的实现是深拷贝还是浅拷贝immutable 来源immutable.js三大特性 持久化数据结构结构共享惰性操作 Immutable.js 的几种数据类型 immutable 使用 使用 npm 安装 immutable 常用API介绍 MapListList.isList() 和 Map.isMap()set() / setIn()get() / getIn()sizeincludes()first() 、 last()is()merge , concatconcat()updateIn() 回调函数更新 – 用法参考setIn()toJS()fromJS()总结增删改查所有操作都会返回新的值不会修改原来值 Immutable-js 优缺点 优点 降低mutable带来的复杂度节省内存历史追溯性时间旅行 缺点 需要重新学习api资源包大小增加源码5000行左右容易与原生对象混淆由于api与原生不同混用的话容易出错。 Immutable-js
Immutable.js,
github地址https://github.com/immutable-js/immutable-js
每次修改一个 Immutable 对象时都会创建一个新的不可变的对象在新对象上操作并不会影响到原对象的数据 这个库的实现是深拷贝还是浅拷贝
Immutable ([ɪˈmjuːtəbl] 不变的不可变的不能变的) 是 Facebook 开发的不可变数据集合。
不可变数据一旦创建就不能被修改使得应用开发更简单允许使用函数式编程技术比如惰性评估。
Immutable JS 提供一个惰性 Sequence允许高效的队列方法链类似 map 和 filter 不用创建中间代表。
immutable 通过惰性队列和哈希映射提供 Sequence, Range, Repeat, Map, OrderedMap, Set 和一个稀疏 Vector。
immutable 来源
Immutable.js出自Facebook是最流行的不可变数据结构的实现之一。
它实现了**完全的 持久化 数据结构**通过使用像tries这样的先进技术来实现结构共享。
所有的更新操作都会返回新的值但是在内部结构是共享的来减少内存占用(和垃圾回收的失效)。
immutable.js三大特性
Persistent data structure 持久化数据结构structural sharing 结构共享support lazy operation 惰性操作
持久化数据结构
这里说的持久化是用来描述一种数据结构
指一个数据在被修改时仍然能够保持修改前的状态即不可变类型。
immutable.js提供了十余种不可变的类型ListMapSetSeqCollectionRange等
结构共享
Immutable使用先进的tries(字典树)技术实现结构共享来解决性能问题.
当我们对一个Immutable对象进行操作的时候
ImmutableJS会只clone该节点以及它的祖先节点其他保持不变这样可以共享相同的部分大大提高性能。 惰性操作
const oddSquares Immutable.seq.of(1, 2, 3, 4, 5, 6, 7, 8).filter(item {console.log(immutable对象的filter执行);return item % 2;}).map(x x * x);console.log(oddSquares.get(1)); // 9const jsSquares [1, 2, 3, 4, 5, 6, 7, 8].filter(item {console.log(原生数组的filter执行);return item % 2;}).map(x x * x);console.log(jsSquares[1]); // 9用seq创建的对象其实代码块没有被执行只是被声明了
代码在get(1)的时候才会实际被执行取到index1的数之后后面的就不会再执行了
所以在filter时第三次就取到了要的数从4-8都不会再执行。
如果在实际业务中数据量非常大一个array的长度是几百要操作这样一个array如果应用惰性操作的特性会节省非常多的性能。
Immutable.js 的几种数据类型
List: 有序索引集类似JavaScript中的Array。Map: 无序索引集类似JavaScript中的Object。OrderedMap: 有序的Map根据数据的set()进行排序。Set: 没有重复值的集合。OrderedSet: 有序的Set根据数据的add进行排序。Stack: 有序集合支持使用unshift()和shift()添加和删除。Record: 一个用于生成Record实例的类。类似于JavaScript的Object但是只接收特定字符串为key具有默认值。Seq: 序列但是可能不能由具体的数据结构支持。Collection: 是构建所有数据结构的基类不可以直接构建。
用的最多就是List和Map这两种数据类型。
immutable 使用
使用 npm 安装 immutable
npm install immutable
js 每个模块都要包括js
var Immutable require(immutable);
var map Immutable.Map({a:1, b:2, c:3});常用API介绍
Map
Map(): 原生object转Map对象 (只会转换第一层注意和fromJS区别)
作用用来创建一个新的Map对象
代码实现
var obj { name: demo, age: 100 }
var oldImmutableObj Map(obj)
console.log(oldImmutableObj)//Map
Immutable.Map(); // 空Map
Immutable.Map({ a: 1, b: 2 });List
List(): 原生array转List对象 (只会转换第一层注意和fromJS区别)
作用用来创建一个新的List对象
代码实现
const { List } require(immutable);
const list1 List([ 1, 2 ]);
const list2 list1.push(3, 4, 5);
const list3 list2.unshift(0);
const list4 list1.concat(list2, list3); assert.equal(list1.size, 2);
assert.equal(list2.size, 5);
assert.equal(list3.size, 6);
assert.equal(list4.size, 13);
assert.equal(list4.get(0), 1); push, set, unshift or splice 都可以直接用返回一个新的immutable对象
List.isList() 和 Map.isMap()
作用判断一个数据结构是不是List/Map类型
用法
List.isList([]); // false
List.isList(List()); // trueMap.isMap({}) // false
Map.isMap(Map()) // trueset() / setIn()
set()修改immutalble的值设置第一层key、index的值
用法
var NewImmutableObj oldImmutableObj.set(name , demo2)const originalList List([ 0 ]);
// List [ 0 ]
originalList.set(1, 1);
// List [ 0, 1 ]
originalList.set(0, overwritten);
// List [ overwritten ]
originalList.set(2, 2);
// List [ 0, undefined, 2 ]const originalMap Map()
const newerMap originalMap.set(key, value)
const newestMap newerMap.set(key, newer value)List在使用的时候将index为number值设置为value。
Map在使用的时候将key的值设置为value。
在List中使用时若传入的number为负数则将index为sizeindex的值设置为value 例若传入-1则将size-1的值设为value。
若传入的number的值超过了List的长度则将List自动补全为传入的number的值将number设置为value其余用undefined补全。
注跟js中不同List中不存在空位[,],List中若没有值则为undefined。
setIn()修改immutalble的值设置深层结构中某属性的值
用法
const originalMap Map({subObject: Map({subKey: subvalue,subSubObject: Map({subSubKey: subSubValue})})
})const newMap originalMap.setIn([subObject, subKey], ha ha!)
// Map {
// subObject: Map {
// subKey: ha ha!,
// subSubObject: Map { subSubKey: subSubValue }
// }
// }const newerMap originalMap.setIn([subObject, subSubObject, subSubKey],ha ha ha!
)// Map {
// subObject: Map {
// subKey: subvalue,
// subSubObject: Map { subSubKey: ha ha ha! }
// }
// }用法与set()一样只是第一个参数是一个数组代表要设置的属性所在的位置
get() / getIn()
get()获取immutalble 获取一级属性的值
//获取List索引的元素
ImmutableData.get(0);// 获取Map对应key的value
ImmutableData.get(a);oldImmuObj.get(name)
newImmuObj.get(name)案例
import React, { Component } from react
import { Map } from immutable export default class App extends Component {state {info: Map({name: demo,age: 100})}render() {return (div this.state.info.get(name) -- {this.state.info.get(name)} br/this.state.info.get(age) -- {this.state.info.get(age)} br/button onClick{(){this.setState({info: this.state.info.set(name,32333).set(age, 1000)})}}修改/button/div)}
}getIn()获取immutalble 获取多级属性的值
// 获取嵌套数组中的数据
ImmutableData.getIn([1, 2]);// 获取嵌套map的数据
ImmutableData.getIn([a, b]); const { Map } require(immutable);
const map1 Map({ a: 1, b: 2, c: 3 });
const map2 map1.set(b, 50);
map1.get(b) vs. map2.get(b); // 2 vs. 50多重对象情况
import React, { Component } from react
import { Map } from immutableexport default class App extends Component { state {info: Map({name: demo,select: aa,fliter: Map({text: ,up: true,down: false})})}componentDidMount() {// console.log(this.state.info)}render() {return (divbutton onClick{() {this.setState({info: this.state.info.set(name, dsdsdd)})}}change/button br /this.state.info.get(name) -- {this.state.info.get(name)} br /Child fliter{this.state.info.get(filter)}/Child/div)}
}class Child extends Component {shouldComponentUpdate(nextProps, nextState) {if (this.props.filter nextProps.filter) { // 注意此处判断是否变化return false}return true}render() {return (divChild -- {this.props.fliter}/div)}componentDidUpdate() {console.log(componentDidUpdate)}
}size
作用属性获取List/Map的长度等同于ImmutableData.count();
用法
// 查看List或者map大小
immutableData.size 或者immutableData.count()
js ### has() 、 hasIn()**作用**判断是否存在某一个key**用法** js
Immutable.fromJS([1,2,3,{a:4,b:5}]).has(0); //true
Immutable.fromJS([1,2,3,{a:4,b:5}]).has(0); //true
Immutable.fromJS([1,2,3,{a:4,b:5}]).hasIn([3,b]) //trueincludes()
作用判断是否存在某一个value
用法
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes(2); //true
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes(2); //false 不包含字符2
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes(5); //false
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes({a:4,b:5}) //false
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes(Immutable.fromJS({a:4,b:5})) //truefirst() 、 last()
作用用来获取第一个元素或者最后一个元素若没有则返回undefined
代码
Immutable.fromJS([1,2,3,{a:4,b:5}]).first()//1
Immutable.fromJS([1,2,3,{a:4,b:5}]).last()//{a:4,b:5}Immutable.fromJS({a:1,b:2,c:{d:3,e:4}}).first() //1
Immutable.fromJS({a:1,b:2,c:{d:3,e:4}}).first() //{d:3,e:4}is()
作用对两个对象进行比较
用法is(map1,map2)
简介
和js中对象的比较不同在js中比较两个对象比较的是地址
但是在Immutable中比较的是这个对象hashCode和valueOf只要两个对象的hashCode相等值就是相同的避免了深度遍历提高了性能
代码实现
import { Map, is } from immutable
const map1 Map({ a: 1, b: 1, c: 1 })
const map2 Map({ a: 1, b: 1, c: 1 })
map1 map2 //false
Object.is(map1, map2) // false
is(map1, map2) // true// is(): 判断两个immutable对象是否相等
const objA { name: graceji, age: 18 };
const objB { name: graceji, age: 18 };
const imA immutable.Map({ name: graceji, age: 18 });
const imB immutable.Map({ name: graceji, age: 18 });
objsA objB // false 比较的是地址
immutable.is(imA, imB); // true; hashcode相同merge , concat
merge
作用浅合并新数据与旧数据对比旧数据中不存在的属性直接添加就数据中已存在的属性用新数据中的覆盖
mergrWith
作用自定义浅合并可自行设置某些属性的值
mergeIn
作用对深层数据进行浅合并
mergeDeep
作用深合并新旧数据中同时存在的的属性为新旧数据合并之后的数据
mergeDeepIn
作用对深层数据进行深合并
mergrDeepWith
作用自定义深合并可自行设置某些属性的值 ’
代码实现
const { Map, List } require(immutable);
const map1 Map({ a: 1, b: 2, c: 3, d: 4 });
const map2 Map({ c: 10, a: 20, t: 30 });
const obj { d: 100, o: 200, g: 300 };const map3 map1.merge(map2, obj);
// Map { a: 20, b: 2, c: 10, d: 100, t: 30, o: 200, g: 300 } 这里用一段示例彻底搞懂merge此示例为Map结构List与Map原理相同
const Map1 Immutable.fromJS({a:111,b:222,c:{d:333,e:444}});
const Map2 Immutable.fromJS({a:111,b:222,c:{e:444,f:555}});
const Map3 Map1.merge(Map2);
//Map {a:111,b:222,c:{e:444,f:555}}const Map4 Map1.mergeDeep(Map2);
//Map {a:111,b:222,c:{d:333,e:444,f:555}}const Map5 Map1.mergeWith((oldData,newData,key){ if(key a){ return 666; }else{ return newData }
},Map2);
//Map {a:666,b:222,c:{e:444,f:555}}concat()
作用对象的拼接用法与js数组中的concat()相同返回一个新的对象。
用法const List list1.concat(list2)
代码实现
const list1 List([ 1, 2, 3 ]);
const list2 List([ 4, 5, 6 ]);
const array [ 7, 8, 9 ];
const list3 list1.concat(list2, array);
// List [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]updateIn() 回调函数更新 – 用法参考setIn() //updateIn 回调函数更新
const nested3 nested2.updateIn([ a, b, d ], value value 1);
console.log(nested3);
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 7 } } }const nested4 nested3.updateIn([ a, b, c ], list list.push(6));
// Map { a: Map { b: Map { c: List [ 3, 4, 5, 6 ], d: 7 } } }toJS()
toJS(): immutable数据转原生js类型的数据 (深度转换会将内部嵌套的Map和List全部转换成原生js)
用法value.toJS()
代码实现
const { Map, List } require(immutable);
const deep Map({ a: 1, b: 2, c: List([ 3, 4, 5 ]) }); console.log(deep.toObject()); // { a: 1, b: 2, c: List [ 3, 4, 5 ] }
console.log(deep.toArray()); // [ 1, 2, List [ 3, 4, 5 ] ]
console.log(deep.toJS()); // { a: 1, b: 2, c: [ 3, 4, 5 ] }
JSON.stringify(deep); // {a:1,b:2,c:[3,4,5]}toJS() mmutable普通对象
oldImmuObj.toJS()
newImmuObj.toJS()案例
import React, { Component } from react
import { Map } from immutable export default class App extends Component {state {info: {name: demo,age: 100}}render() {return (div this.state.info.name -- {this.state.info.name} br/this.state.info.age -- {this.state.info.age} br/button onClick{(){var old Map(this.state.info)var newData old.set(name,32333).set(age, 1000)this.setState({info: newData.toJS()})}}修改/button/div)}
}fromJS()
fromJS(): 原生js转immutable对象 (深度转换会将内部嵌套的对象和数组全部转成immutable)
用法fromJS(value, converter)
简介value是要转变的数据converter是要做的操作。第二个参数可不填默认情况会将数组准换为List类型将对象转换为Map类型其余不做操作
const { fromJS } require(immutable);
const nested fromJS({ a: { b: { c: [ 3, 4, 5 ] } } });
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ] } } } const obj fromJS({a:123,b:234},function (key, value, path) {console.log(key, value, path)return isIndexed(value) ? value.toList() : value.toOrderedMap())
})总结增删改查所有操作都会返回新的值不会修改原来值
代码实现
// 增删改查所有操作都会返回新的值不会修改原来值
const immutableData immutable.fromJS({a: 1,b: 2c: {d: 3}
});
const data1 immutableData.get(a) // data1 1
const data2 immutableData.getIn([c, d]) // data2 3; getIn用于深层结构访问
const data3 immutableData.set(a , 2); // data3中的 a 2
const data4 immutableData.setIn([c, d], 4); // data4中的 d 4
const data5 immutableData.update(a , function(x) { return x4 }) // data5中的 a 5
const data6 immutableData.updateIn([c, d], function(x) { return x4 }) // data6中的 d 7
const data7 immutableData.delete(a) // data7中的 a 不存在
const data8 immutableData.deleteIn([c, d]) // data8中的 d 不存在案例
import React, { Component } from react
import { fromJS } from immutable
export default class App extends Component { // state {// info:Map({// name:demo,// location:Map({// province:辽宁,// city:大连// }),// favor:List([读书,看报,写代码])// })// }// 使用 fromJS 转换成 immutable对象state {info:fromJS({ // 注意这里 fromJS -- 转换成 immutable对象name:demo, location:{province:辽宁,city:大连},favor:[读书,看报,写代码]})
} render() {return (divh1个人信息修改/h1 div{this.state.info.get(name)} button onClick{(){this.setState({info: this.state.info.set(name,demo33).setIn([location,city],wuhan) // 注意这里 setIn([location,city],wuhan)})}}修改/button/divdiv{this.state.info.get(location).get(province)} -- {this.state.info.get(location).get(city)}/divul{this.state.info.get(favor).map((item,index)li key{index}{item} button onClick{(){this.setState({info: this.state.info.updateIn([favor],(list)list.splice(index,1)) // 注意这里 updateIn([favor],(list)list.splice(index,1))})}}删除/button/li)}/ul/div)}
}Immutable-js 优缺点
优点
降低mutable带来的复杂度
节省内存
历史追溯性时间旅行
时间旅行指的是每时每刻的值都被保留了想回退到哪一步只要简单的将数据取出就行。
如果现在页面有个撤销的操作撤销前的数据被保留了只需要取出就行这个特性在redux或者flux中特别有用
拥抱函数式编程immutable本来就是函数式编程的概念纯函数式编程的特点就是只要输入一致输出必然一致相比于面向对象这样开发组件和调试更方便
缺点
需要重新学习api
资源包大小增加源码5000行左右
容易与原生对象混淆由于api与原生不同混用的话容易出错。 文章转载自: http://www.morning.ctxt.cn.gov.cn.ctxt.cn http://www.morning.ngdkn.cn.gov.cn.ngdkn.cn http://www.morning.wpkr.cn.gov.cn.wpkr.cn http://www.morning.kbynw.cn.gov.cn.kbynw.cn http://www.morning.llxqj.cn.gov.cn.llxqj.cn http://www.morning.tbwsl.cn.gov.cn.tbwsl.cn http://www.morning.fmdvbsa.cn.gov.cn.fmdvbsa.cn http://www.morning.drgmr.cn.gov.cn.drgmr.cn http://www.morning.khxwp.cn.gov.cn.khxwp.cn http://www.morning.hpcpp.cn.gov.cn.hpcpp.cn http://www.morning.rdxp.cn.gov.cn.rdxp.cn http://www.morning.qjsxf.cn.gov.cn.qjsxf.cn http://www.morning.jykzy.cn.gov.cn.jykzy.cn http://www.morning.fhlfp.cn.gov.cn.fhlfp.cn http://www.morning.tthmg.cn.gov.cn.tthmg.cn http://www.morning.glnxd.cn.gov.cn.glnxd.cn http://www.morning.rppf.cn.gov.cn.rppf.cn http://www.morning.bojkosvit.com.gov.cn.bojkosvit.com http://www.morning.rglzy.cn.gov.cn.rglzy.cn http://www.morning.yrkdq.cn.gov.cn.yrkdq.cn http://www.morning.tgfsr.cn.gov.cn.tgfsr.cn http://www.morning.cykqb.cn.gov.cn.cykqb.cn http://www.morning.yxzfl.cn.gov.cn.yxzfl.cn http://www.morning.zhffz.cn.gov.cn.zhffz.cn http://www.morning.thzgd.cn.gov.cn.thzgd.cn http://www.morning.qqrqb.cn.gov.cn.qqrqb.cn http://www.morning.mmynk.cn.gov.cn.mmynk.cn http://www.morning.mzcsp.cn.gov.cn.mzcsp.cn http://www.morning.rrpsw.cn.gov.cn.rrpsw.cn http://www.morning.ftrpvh.cn.gov.cn.ftrpvh.cn http://www.morning.jcbjy.cn.gov.cn.jcbjy.cn http://www.morning.gdljq.cn.gov.cn.gdljq.cn http://www.morning.wqbhx.cn.gov.cn.wqbhx.cn http://www.morning.szoptic.com.gov.cn.szoptic.com http://www.morning.yhwyh.cn.gov.cn.yhwyh.cn http://www.morning.qxmnf.cn.gov.cn.qxmnf.cn http://www.morning.bpyps.cn.gov.cn.bpyps.cn http://www.morning.jtfcd.cn.gov.cn.jtfcd.cn http://www.morning.srbmc.cn.gov.cn.srbmc.cn http://www.morning.gjtdp.cn.gov.cn.gjtdp.cn http://www.morning.lnfkd.cn.gov.cn.lnfkd.cn http://www.morning.rmqmc.cn.gov.cn.rmqmc.cn http://www.morning.wqbzt.cn.gov.cn.wqbzt.cn http://www.morning.nfqyk.cn.gov.cn.nfqyk.cn http://www.morning.ptqpd.cn.gov.cn.ptqpd.cn http://www.morning.ndpwg.cn.gov.cn.ndpwg.cn http://www.morning.mjpgl.cn.gov.cn.mjpgl.cn http://www.morning.tjjkn.cn.gov.cn.tjjkn.cn http://www.morning.xkyqq.cn.gov.cn.xkyqq.cn http://www.morning.gsrh.cn.gov.cn.gsrh.cn http://www.morning.qytyt.cn.gov.cn.qytyt.cn http://www.morning.rfbt.cn.gov.cn.rfbt.cn http://www.morning.rhmpk.cn.gov.cn.rhmpk.cn http://www.morning.gediba.com.gov.cn.gediba.com http://www.morning.lpnpn.cn.gov.cn.lpnpn.cn http://www.morning.gwqkk.cn.gov.cn.gwqkk.cn http://www.morning.stflb.cn.gov.cn.stflb.cn http://www.morning.kstlm.cn.gov.cn.kstlm.cn http://www.morning.lstmg.cn.gov.cn.lstmg.cn http://www.morning.kgrwh.cn.gov.cn.kgrwh.cn http://www.morning.nwnbq.cn.gov.cn.nwnbq.cn http://www.morning.trqhd.cn.gov.cn.trqhd.cn http://www.morning.qqfcf.cn.gov.cn.qqfcf.cn http://www.morning.czxrg.cn.gov.cn.czxrg.cn http://www.morning.ftzll.cn.gov.cn.ftzll.cn http://www.morning.rnyhx.cn.gov.cn.rnyhx.cn http://www.morning.rkjz.cn.gov.cn.rkjz.cn http://www.morning.zyndj.cn.gov.cn.zyndj.cn http://www.morning.grwgw.cn.gov.cn.grwgw.cn http://www.morning.hryhq.cn.gov.cn.hryhq.cn http://www.morning.lbxcc.cn.gov.cn.lbxcc.cn http://www.morning.mxnhq.cn.gov.cn.mxnhq.cn http://www.morning.sjqml.cn.gov.cn.sjqml.cn http://www.morning.sphft.cn.gov.cn.sphft.cn http://www.morning.kfmlf.cn.gov.cn.kfmlf.cn http://www.morning.tfsyk.cn.gov.cn.tfsyk.cn http://www.morning.cnprt.cn.gov.cn.cnprt.cn http://www.morning.bqdpy.cn.gov.cn.bqdpy.cn http://www.morning.tkrpt.cn.gov.cn.tkrpt.cn http://www.morning.lzqtn.cn.gov.cn.lzqtn.cn