你应该知道的关于Javascript字典的一切

196 阅读7分钟

你应该知道的关于Javascript字典的一切

了解如何构建和使用这种天才的数据结构

等等!Javascript现在有字典类型了吗?不完全是。至少,现在还没有。

但是有了它一直以来都很灵活的Object和ES6 Map类型,创建一个类似字典的对象来存储键值对的数据只是几分钟的事情。

如果你来自静态类型语言的背景,这句话可能对你来说有点奇怪。但由于其动态类型的特性,用Javascript实现这一点完全不是问题。所以,在今天的文章中,让我们来谈谈如何在Javascript中成功地创建字典,并使用替代的数据结构访问存储的数据。


用Javascript对象创建字典

Javascript对象类型为我们提供了足够的灵活性,可以像标准字典那样以键值对的形式存储数据。但它的多功能性并没有结束。对象类型还支持使用键来访问存储的数据,通过键和值进行迭代,甚至使用不同的数据类型作为键。

而这一切都要从使用 Object 创建一个新的字典开始。下面是我们如何做到这一点的:

let dict = {
    id: 123,
    name: "Anj",
    age: 28,
    registered: true
}

作为创建字典的另一种方法,你可以先初始化一个 Object 实例,并按以下方式用键值对填充它:

//Create a new Object
let dict = new Object()

//Populate data
dict["id"] = 123
dict["name"] = "Anj"
dict["age"] = 28
dict["registered"] = true

我们可以再往前走一步,创建一个原型为空的对象。它删除了所有从 Object.prototype 继承的方法。它最适合我们,因为这些对象方法对于字典来说是不必要的。这包括诸如hasProperty(),hasOwnProperty(),toString(),valueOf() 等方法。

下面是如何修改Object的创建步骤,以获得一个原型为空的对象:

let dict = Object.create(null)

Javascript 允许我们为键和值分配不同的数据类型--包括字符串、整数和浮点,甚至在同一个字典中:

let dict = {
    "color": "red",
    1: [12, 14, 90],
    1.2: 123,
} 

你甚至可以把一个Javascript方法作为一个值存储在一个基于Object的字典中:

const method = () => console.log("Hello");

let dict = {
    "method": method,
}

然而,当存储字符串以外的键时,Object在存储前会隐含地将它们转换为字符串类型。例如,这就是Javascript在创建上述字典时对其键值的转换:

{
  '1': [ 12, 14, 90 ],
  color: 'red',
  '1.2': 123,
}

使用键访问数据

能够使用键来检索一个特定的键值对是字典数据结构最宝贵的特性之一。有了Javascript Object类型,做到这一点就像下面的例子所显示的那样简单:

let dict = {
    "color": "red",
    1: [12, 14, 90],
    1.2: 123
}   

dict["color"] //red
dict[1] //[12, 14, 90]
dict[1.2] //123

//Use key as a property 
dict.color //red

正如这个例子所示,你可以使用任何键作为索引来检索与之相关的值。对于字符串类型的键,你可以通过将键视为对象的一个属性来访问该值。

遍历键值对

Javascript对象类型提供了几种方法来遍历键、值或键值对,具体取决于使用情况。

首先,让我们看看如何使用Object.keys方法来遍历字典中的键:

for (const key of Object.keys(dict)) {
    console.log(key + ":" + dict[key])
}

在 Object.values 方法的帮助下,遍历 dictionary 中的值也遵循同样的模式:

for (const value of Object.values(dict)) {
    console.log(value)
}

我们也可以使用 Object.entry 方法在同一个循环中迭代键和值对:

for (const [key, value] of Object.entries(dict)) {
    console.log(key + ":" + value)
}

从字典中删除一个键值对

我们可以使用 Javascript 的 delete 操作符从基于 Object 的字典中删除一个键值对。比如说:

let dict = {
    id: 123,
    name: "Anj",
    age: 28,
    registered: true
}

delete dict["registered"] 
dict //{ id: 123, name: 'Anj', age: 28 }

使用删除操作符来删除一个键值对的一个缺点是,它降低了你的代码的性能。如果你更关心性能而不是从字典中完全删除这个属性,你可以把它的值设置为null或undefined来标记一个 "删除 "的属性:

dict["registered"] = undefined
dict //{ id: 123, name: 'Anj', age: 28, registered: undefined }

尽管这个方法并没有完全删除该属性,但它完成执行的速度比删除操作符快得多。

至此,我们已经讨论了在Javascript中借助其对象类型创建字典的基本知识。在下一节,让我们看看如何使用ES6地图获得类似的结果。


用Javascript地图创建字典

ES6中引入的Javascript Maps是另一种用于创建字典的优秀选择。事实上,当涉及到像字典一样的功能时,Maps比普通的Object有更多的优势。我们在下面列出了在这个用例中使用Maps而不是Objects的一些主要好处:

  • 地图中的键可以是任何类型的。除了Objects所接受的原始类型和字符串类型外,它还包括Objects作为键的类型。而且Maps保留了键的初始类型,而不像Objects那样隐含地将它们转换为字符串。
  • Map按照我们插入的顺序排列其键值对。但是Objects中的排序并不像Maps那样可靠和直接。
  • Maps有一个 "size "属性,可以直接检索存储的键值对的数量。对于Objects,我们必须在Object.keys或类似方法的帮助下手动计算大小。

那么,我们怎样才能用Maps创建字典呢?让我们来了解一下:

//Create Map instance
let dict = new Map()

//Add key-value pairs
dict.set("id", 123)
dict.set("registered", true)

let person = {name: "Anj"}

//Add keys of different types
dict.set(1, [1, 2, 3, 5])
dict.set(person, "available")

这给我们返回一个保留了键类型的地图:

Map(4) {
  'id' => 123,
  'registered' => true,
  1 => [ 1, 2, 3, 5 ],
  { name: 'Anj' } => 'available'
}

使用键访问数据

ES6 Maps提供了一个专门的 "get "方法来检索基于键的数据。下面是我们如何使用它来访问存储的键值对:

dict.get("id") //123
dict.get("registered") //true
dict.get(1) //[1, 2, 3, 5]
dict.get(person) //available

通过键值对进行迭代

Javascript中的Maps类型是可以直接迭代的。因此,我们不必使用一个额外的方法,如Object.keys来检索存储在地图中的键值对的集合。相反,我们可以使用for...的循环来迭代数据,就像下面的代码片段所示:

for (const [key, value] of dict) {
    console.log(key + ": " + value)
}

地图还提供了单独的 entries()、keys()和values()函数,根据不同的使用情况,以不同的方式遍历key和value:

for (const [key, value] of dict.entries()) {
    console.log(key + ": " + value)
}

for (const key of dict.keys()) {
    console.log(key)
}

for (const value of dict.values()) {
    console.log(value)
}

从字典中删除一个键值对

同样,Maps有一个专门的方法来删除一个存储的键值对。如果删除操作完成,它返回true,否则返回false:

dict.delete(person) //true

dict //Map(3) { 'id' => 123, 'registered' => true, 1 => [ 1, 2, 3, 5 ] }

使用Maps的其他字典操作

除了我们到目前为止所讨论的以外,Maps还支持几个方法,使我们能够与字典交互。例如,我们可以使用下面的has 方法来检查字典是否包含一个特定的键:

dict.has("dog") //false
dict.has("id") //true

使用size 获取字典的大小:

dict.size

总结

尽管 Javascript 没有内置的 Dictionary 数据类型,但它的 Object 和 Map 类型的行为与 Python 等语言中的 dictionary 相似。在今天的教程中,我们谈到了使用这些替代类型来存储和访问Javascript中的键值对,就像一个标准的字典那样。

所以,下一次,当你想找一个像字典一样的东西来解决问题时,你可以根据你的要求,从我们这里提供的两个选项中选择一个。