Immutable's Map与JavaScript对象很相似,但是如果你不知道它是如何工作的话,它可能会严重地影响你。这篇文章是第一次深入了解Immutable Maps,向您展示如何以正确的方式使用它们。
认识认识 Immutable 中的Map
一个不可变映射是键/值对的无序集合,乍一看似乎与JavaScript对象相似。但是,它具有以下附加属性:
- 您可以迭代Map中的键
- 迭代的键的顺序不会改变(尽管你不知道什么顺序会提前)
- 所有的键都被转换成字符串。
- 一个键可以是任何类型的 - 甚至是NaN和一个数组
- 如果Immutable.is(map1,map2)返回true,则两个映射是相同的
- 一个不可变的集合(例如List,Map,Seq等)可以是一个Key
Create an empty Map
// Empty Map:const map = Immutable.Map();// Output:map;
Create a populated Map of data
您可以使用Map()
构造函数或Map.of()
方法根据现有数据创建Map,具体取决于您用于创建Map的数据类型:
Map.of()
从一组函数参数中创建Map时使用,每对参数都被解释为一个键和一个值;Map()
使用其他方式创建Map时使用。
Create a new Map from…
…a JavaScript Array
要从数组创建一个新的Map,实际上需要一个数组中的数组,每个数组项都是一个元组(即有两个值)。每个数组项的第一个值将被用作MAP中的一个键,第二个项将是它的值。
// New Map from JavaScript arrayconst avengersArray = [ ['heroName1', 'ironMan'], ['heroName2', 'captainAmerica']];const avengersMap = Immutable.Map(avengersArray);// Output:avengersMap;{ heroName1: "ironMan", heroName2: "captainAmerica"}
重要提示:请记住,密钥名称必须是唯一的。尝试在上面的代码中将“heroName2”更改为“heroName1”,看看会发生什么。这是因为不可变将覆盖它看作是一个重复的密钥。
…a JavaScript Object
// New Map from JavaScript objectconst avengersObj = { ironMan: 'Tony Stark', captainAmerica: 'Steve Rogers'};const avengersMap = Immutable.Map(avengersObj);// Output:{ captainAmerica: "Steve Rogers", ironMan: "Tony Stark"}
...深度嵌套的JavaScript对象或JSON编码的数据
Immutable的Map
不能在深度嵌套的对象上工作,因为它只会进行浅转换(例如,obj.key
中的键将被转换为Map,但obj.key.subkey
中的子键将保持不变 - 也就是说,如果subkey
是一个JavaScript对象,它将保持一个JavaScript对象,而不是一个不可变的映射)。
为了从一个复杂的对象或JSON编码的数据创建一个新的Map,因此,您需要使用fromJS()。
// New Map from deeply nested JavaScript objectconst avengers = { hero1: { ironMan: { realName: 'Tony Stark' } }, hero2: { captainAmerica: { realName: 'Steve Rogers' } }};// Create the Mapconst avengersMap = Immutable.Map(Immutable.fromJS(avengers));// Test that we have a deeply nested Mapconst ironMan = avengersMap.getIn(['hero1', 'ironMan']);// Output:Immutable.Map.isMap(ironMan);
尝试从上面的代码中删除Immuable.fromJS,你应该看到输出转为false。这是因为,如果没有fromJS(),深层嵌套的对象将不会被转换为一个Map。
…a set of function arguments
您可以从任意数量的函数参数创建一个Map,每个参数对被解释为一个键/值对。只要记住用Map.of()
创建你的Map
// New Map from function argumentsconst avengersMap = Immutable.Map.of( 'ironMan', 'Tony Stark', 'captainAmerica', 'Steve Rogers');// Output:avengersMap;
…a JavaScript iterator
可以使用内置的(例如一个数组)或用户定义的任何ES6可迭代对象来创建一个新的不可变映射。
// New Map from existing JavaScript iterator (Array.map example)// Note: an ES6 object is not an iterator, so we'll use an array insteadconst avengersArray = ['ironMan' , 'captainAmerica'];const avengersMap = Immutable.Map(avengersArray.map( (item, index) => ([ 'heroName' + index, item ])));// Output:avengersMap;
…an Immutable List
就像从数组创建Map一样,List必须包含List列表,每个List项都是一个元组,它将被Map用作键/值对。
// New Map from existing Listconst avengersList = Immutable.List([['heroName1', 'ironMan'], ['heroName2', 'captainAmerica']]);const avengersMap = Immutable.Map(avengersList);// Output:avengersMap;{ heroName1: "ironMan", heroName2: "captainAmerica"}
…an Immutable Map
// New Map from existing Mapconst avengersMap = Immutable.Map({ hero1: 'ironMan', hero2: 'captainAmerica', hero3: 'blackWidow'});const newAvengersMap = Immutable.Map(avengersMap);// Output:newAvengersMap; { hero1: "ironMan", hero2: "captainAmerica", hero3: "blackWidow"}
…other Immutable objects
您可以使用任何不可变对象创建新的Map,其中包括:
- List
- Map
- OrderedMap
- Set
- OrderedSet
- Stack
- Record
OrderedMap
一个OrderedMap和Map一样,但是保证迭代的键顺序总是一样的。您可以使用Map执行的其他操作,OrderedMap也可以使用。
请注意,OrderedMap比Map更慢,所以如果你不关心被迭代的键的顺序,可以使用Map。
Get, Set, Update and Delete Map properties
如你所看到的,创建地图可能会非常复杂。一旦创建,他们提供了一个强大的方式来执行数据操作。本系列的下一篇文章将介绍如何从Map中获取,设置,更新和删除。