ImmutableJs 提供了大量的内置对象,它们和 js 的原生对象不同,可以互相转换。
这意味着在使用 ImmutableJs 时,对原来的代码会有比较大的侵入型,需要改造。
const { Map, List } = require("immutable");
const assert = require("assert");
// Immutable Map 对象
const map1 = Map({ a: 1, b: 2, c: 3 });
const map2 = map1.set("b", 3); // 更新属性,根据Immutable定义,返回一个崭新对象
console.log(map1.get("b"), map2.get("b"));
// Immutable List 对象
const list1 = List([1, 2]);
const list2 = list1.push(3, 4, 5);
const list3 = list2.unshift(0);
const list4 = list1.concat(list2, list3);
// 以下验证都能通过,长度不同说明list1 ~ list4,每个都是一个崭新对象
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);
除了常见的数据类型,immutable.js 额外提供了 SortedMap 、SortedSet、Stack、Recodr、Range 等对象。
在 js 中,对于复杂对象,===
运算符是基于指针进行比较的。
而在 immutable.js 中,由于每次操作都返回一个新对象,所以对象的指针肯定不同。对于 Immutable,比较本身也是基于对象的值(value)来进行的。
可以将 Immutable 的对象看作 collection,决定 collection 性质的是它的 values,而不是 references。
const map3 = Map({ a: 1, b: 2, c: 3 });
const map4 = Map({ a: 1, b: 2, c: 3 });
console.log(map3.equals(map4)); // true
console.log(map3 === map4); // false
如果 values 不变,那么会避免创建新对象。所以利用===
比较后,是相等的:
const originalMap = Map({ a: 1, b: 2, c: 3 });
const updatedMap = originalMap.set("b", 2);
// output: true
console.log("originalMap === updatedMap: ", originalMap === updatedMap);
immutable 对象,可以和 js 的 Array、Object 进行转换。
转换 Map 和原生 JSON:
const { Map, List, fromJS } = 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);
console.log(map3.toJSON()); // 转换为 json
// output: { a: 20, b: 2, c: 10, d: 100, t: 30, o: 200, g: 300 }
转换 List 和原生 List:
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.toArray()); // toArray、toObject都是将其转换为js原生对象(非递归)
fromtJS()
和 toJS()
操作嵌套对象: