ES6 的 Map 避免了原始值转换的损失
JavaScript 中的对象与原始值不同,在将它们传递给函数或分配给不同变量时,它们始终按引用传递。引用是内存中对象的地址。如果两个引用指向同一对象,则更改该对象也会影响到另一个引用。但是,当尝试使用原始值作为键时,会发生什么呢?例如,如果我们将数字 1 作为键使用:
const map = new Map(); map.set(1, 'one'); console.log(map.get('1')); // undefined
上述代码中,我们使用数字 1 作为键将值 'one' 存储在一个 Map 中。但是,当我们使用字符串 '1' 来检索该值时,我们却得到了 undefined。
这是因为在 Map 中,键的值不会自动转换为字符串,如对象和原始类型一样,每个键都有一个对应的内部 ID,因此按照自己的方式处理每个类型的键。
使用原始值时,键保留不变。没有任何类型转换的损失或歧义。
如何在 Map 中使用实际类型
现在我们已经确保键保留不变,那么如何在 Map 中使用实际类型呢?即,如何在保留类型的情况下,将它们用作键?
假设我们有一个数据结构,其中每个对象都具有一个唯一 ID 属性。我们想在 Map 中存储这些对象,并使用它们的 ID 作为键。
我们可以使用对象本身作为键,例如:
-- -------------------- ---- ------- ----- ------- - - - --- -- ----- ------- -- -- - --- -- ----- ------- -- -- - --- -- ----- ------- -- -- -- ----- ---- - --- ------ ---------------------- -- - ---------------- ------------- --- ---------------------------------- -- ------ -
这种方法可以工作,这是因为键已被视为对于对象的引用,而不是具有任何类型的标量值。当使用相同的引用检索价值时,我们获得了期望的值。
但是,如果我们尝试使用相同的数据结构,但在每个对象上添加另一个属性,例如 uuid 属性,我们会得到不同的结果:
-- -------------------- ---- ------- ----- ------- - - - --- -- ----- ------- --- ----- --------- -- - --- -- ----- ------- --- ----- -------- -- - --- -- ----- ------- --- ----- -------- - -- ----- ---- - --- ------ ---------------------- -- - ---------------- ------------- --- ------------------------- -- ----- ------- --- ----- ------------- -- ---------
因为我们现在得到的对象与原始对象不同,所以 Map 无法找到键。但是,如果使用 ES6 Map 中提供的新特性,即使用独特的键作为参数来创建 Map,该问题将得到解决。
-- -------------------- ---- ------- ----- ------- - - - --- -- ----- ------- --- ----- --------- -- - --- -- ----- ------- --- ----- -------- -- - --- -- ----- ------- --- ----- -------- - -- ----- ---- - --- ---- ------------------ -- -------- ------------- -- ------------------------- -- ----- ------- --- ----- ------------- -- ------ -
在这个例子中,我们使用 Map 构造函数中的映射格式,其中将一个数组的元素与它的返回值映射到一个数组。键是原始对象,值是对象的名称。这样,我们就可以使用具有相同 ID 的不同对象来访问 Map 中的值。
结论
在 ES6 中,Map 避免了原始值转换的损失,并提供了一种使用对象作为键的方法。这样,我们就可以在保留对象类型的同时将它们用作 Map 中的键。
使用 ES6 Map 可以更清晰和可读的程序,更少的错误和更好的JavaScript类型安全。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6771f4626d66e0f9aad325f1