乐趣区

初学immutable.js的一些总结

1.immutableObj 在复制的时候,复制的是引用。
=== 比较的是引用是否一样。而 is()和 equal()表示的是值是否一样,什么是值,我认为就是将一个对象 Json.stringify()之后的的数据。
总体而言,如果 === 相等,那么使用 equal()和 is()也是相等的;如果只是 is 和 equal()相等,可能 === 相等,也可能是两个对象被 json.stringify()之后的字符串是相等的。
如果是像 map1 = map3 的赋值操作,其实这里复制的是引用。就上面的结论可知,只要引用向相同,=== 和 equals() 返回的都是 true.
2.immutable 中的对象的使用和 es2015 灰常的像,一个最大的区别,就是不管啥时候,返回值都是一个新的 immutable 集合。比如 arr=[1,2] ,arr.push(3,4)的返回值是 4,即 arr 的新长度。在 immutable 中,arr1=List([1,2]) , arr1.push(3,4)的返回值是 List([1,2,3,4]),即一个新的 immutable 对象。
3.immutable 对象和 es2015 中原生的对象是可以自由合并的。啥意思?就是当 obj 被 immutable 的 Map 对象 merge,或者是 array 被 immutable 的 List 来 concat 的时候,es2015 中的 array 和 object 就被自动对应转换成了 List 和 Map.
说白了,就是当 Array 或者 Object 被传入 immutable 的 List 和 Map 使用的方法的时候,会做一个类型检测,如果接受的参数是 Array, 就将该 Array 转换成 List, 如果参数是 Object, 就将该 Object 转换成 Immutable 的 Map.
换一个角度看,这可以让我们更灵活的合并处理 es2015 的原生对象和 immutable 对象。即扩展了 es2015 原生对象的方法集。
注意:使用 immutable 对象的 api 将 es2015 原生对象 Object 转换成 immutable 中的 map 的时候,这个 Object 的所有 key 值都会被作为字符串处理。
如果 Object 使用的是 [变量] 的方式设置的 key 值,当使用 immutable 的 map 的 api 将其转换成 map 的时候,这个 key 值就是 [变量] 中的 ” 变量 ” 指代的字符串。但如果变量指代的不是字符串,而是对象呢?==> 当然是把这个对象 stringy 成一个字符串啊
4.immutable 对象怎样转换成 es2015 的原生对象呢?这里的转换有三种:对应浅拷贝的浅转换;toObject() / toArray()对应深拷贝的深转换;toJS() , toJSON()直接转换成字符串; JSON.stringify(immutableObj)注意:这里的 toObject() / toArray / toJS() / toJSON 都是 map 和 list 通用的。
5. 所有的 immutable 的对象都是 iterable 对象,这可就意味着它可以被 yield, 可以被 for of,也可以被 … 符号所展开。
6. 操作嵌套 immutable 数据结构的有效方式就是使用专门操作嵌套数据的 api. 比如 mergeDeep(),getIn(),setIn(),updateIn(). 这 4 个方法被使用在 List,Map 和 OrderedMap 对象上。getIn()/setIn()/updateIn()传递的第一个参数是 key 值组成的路径。而 mergeDeep()传递的参数是一个嵌套 Obj.
7. 当 map 在使用自己的 api 来 update 自己的时候,如果 update 的结果和自己原本是一模一样的,那么该 update 的 api 返回的对象的引用和自己是一样的。当 update 之后的结果和自己不同,那么 update 返回的对象会被在内存中新建一个引用。
es2015 中原生的 map 如果使用 set()更新了自己的数据,不管更新之后,数据有没有变化,set()方法返回的引用都是一样的。
8. 如果想要多次更改某个 immutable 对象,但是却只需要生成一个新的 immutable 对象,可以使用 withMutations()方法。在这个方法中,只能够使用 set,push,pop,clear,unshift,shift ,update,setIn,updateIn , mergeIn,mergeDeepIn() , concat()方法。
9.seq 是一种可以使用链式书写的对象。它在使用链式书写的时候,只会产生一个新对象,链式中间的操作是不会产生新的对象的。其他的常用对象,比如 Map 和 List 可以通过 Seq()转换成一个 seq 对象。但是事实上,这种对象有什么样的具体作用还尚不清楚。
下面挑选了 List 对象来进行深度分析,下面是一些 API 的记录:
/**

List 对象可以由 3 种方式转换而成。
(1) es2105 中的 Array;
(2) es2015 中的 set
(3) immutable 中的 set
(4) es2015 中的 Array 或者 set 的遍历器接口:someArray[Symbol.iterator]()

*
可以通过 List.of()方法构造 List. 这个和 es2015 的 Array.of()是一样的。
*

更新 List 中的值使用的是 set()方法,这个和 es2015 中的 Array 和 set 都不同,和 es2015 的 map 设置值的方式是一样的。
这里的 set()方法的第一个参数是索引,该索引可以是负数,用法和 Array 中使用 slice()方法参数为负数是一样的。

*

删除 List 中的数据,使用的是 delete()方法。该方法在 es2015 中的 set 和 map 中均有使用,但是此处的 delete()方法返回的是
一个布尔值。而 List 中使用的 delete()方法更像 Array 中的 splice(index,1),只不过,delete()的返回值是一个新的 List,
而 splice()返回的是被删除的项目。

*
向 List 中增加数据,使用的是 insert()方法,和 Array 中的 splice(index, 0 , value)一样。返回的是一个新的 List()对象。
*

对 List 的首尾增减使用的是和 es2015 中的 Array 一样的方式,只不过这 4 个 api 返回的都是一个新的 List 对象。
push(), pop(), shift(), unshift()

*

如果想要更新 List 中某一个已有项目的 value, 使用的是 update()方法。这个方法接受 2 个参数,第一个参数是索引,第二个参数
是一个函数,这个函数接受之前在该索引位置的值作为参数,返回一个新 value, 可以是任意类型。注意,update()是更新已有的值,
set()是设置某个位置上的值,如果那个位置上已经有值,使用 set()设置之后,该位置上的值会被替换。

*

如果想要向 Array 设置 length 一样,粗暴地重置一个 List 的长度,使用的方法是 setSize()方法。二者效果是一致的。
setSize()返回一个新长度的 List()对象。

*

如果想要深度设置 List 内部嵌套的数据,使用 setIn()方法,第一个参数是索引组成的路径。第二个参数是新设置的值。
话说这个嵌套是个什么嵌套法?
当嵌套的是 Array 或者是 List 的时候,path 中都是索引;当嵌套的是 Object 或者是 Map 的时候,path 是索引和 key 组合的。

*

如果想更新嵌套 List, 使用的 api 是 updateIn(),该参数接受两个参数,一个是索引组成的 path, 第二个依旧是一个函数,接受
该位置老数据作为参数。

*

类似于 Array 中的其他方法,比如 concat(),map(),filter()方法的使用都和 Array 是一样的,只不过这几个方法返回的都是新的
List 对象。然后在 map()和 filter()方法中的 item 都是一个 Immutable 对象。

*
另,List 中的还有 filterNot()方法,其实就是对 filter()方法取反。其他的使用方法一样,也是返回一个布尔值。
*

另,List 中还有 reverse()和 sort()方法,reverse()方法和 Array 中的 reverse()方法是一样的,都是用来将索引翻转。
sort()是排序方法,可以传入一个函数,通过返回值的正负确定元素的前后排序顺序。

*

如果是一个简单 map 调用 sort()进行排序,sort((a,b)=>{})中的 a 和 b 是 map 中的第一层 value.
如果是一个复杂的 map 想要使用 sort 来排序,可能由于 value 的数据类型不同,sort()函数根本就无法比较。
此时需要使用 sortBy()函数,该函数接受两个参数,第一个参数用来指定要比较的是每一个 map 项目中的某个部分,
第二个参数和 sort()函数接受的回调是一样的,即比较那一项,根据返回值的正负确定排序。

**

如果想要将一个 List 转换成 Array, 有浅转换和深转换。
someList.toJS() : 递归转换 List 成 es2015 中的 array, 将 List 中的所有项目转换成 Array 和 object;

*

someList.toJSON() 和 someList.toArray() 都是将一个 List 浅转换成 array, 也就是说,将这个 List 转换成 Array, 这
个 array 中的 items 的类型是不会被转换的。之前的 List 中的第一层数据如果有 List 和 Map, 那么浅转换之后的 Array 的
第一层 item 还是 List 和 Map.

*
someList.toObject()可以将 List 转换成 key 是 string 的 Object.
**

上面的方法都是讲怎么操作整个 List 的。下面的有几个方法讲怎么获取 List 中的 item. 或者给 item 赋值的。
get(index)获取某个索引位置的 value;
has(index) 判断某个索引是不是存在的。比如一个 List 的 size 是 6,那么 has(7)肯定返回 false.
includes(value) 判断 List 中存在某个 value. 这个参数 value 如果和 List 中的某个 value 是值等的,就返回 true.

**
另,在 Array 中还有 splice()方法啊,indexof(), lastIndexOf(), List 中也有这些方法,使用效果都是一样的。
*
**/

退出移动版