Open afishhhhh opened 5 years ago
在 JavaScript 中,一个普通的 Object
也是一个类似 Map
的集合数据类型,遵循键值对存储的概念,每一个 property
都有一个唯一的值与其对应。
JavaScript 中所有的对象都继承自 Object
,包括 Map
。
Object
可以通过构造函数或者字面量来创建一个实例,Map
则只能通过 new Map
来创建一个实例。因为字面量构建的效率比构造函数更高,由此看来创建一个 Object
实例的效率比 Map
更胜一筹。
Map
的键可以是任意数据类型,而 Object
只能是 String
或者 Symbols
。 虽然看上去 Object
可以接受一个 Number
、Function
甚至 Object
作为属性名,但是实际上 JavaScript 会对 Object
的属性名做一次 toString()
,所以属性名还是一个 String
类型。
const fn = function () {}
const o = {}
o[fn] = 'function'
o[fn] // function
o['function () {}'] // function
另外 Map
的键是有序的,能够保持键值对添加时的顺序,但 Object
是无序的。
Map
has
方法检查元素是否存在
const m = new Map()
m.set(1, 'value1')
m.has(1) // true
m.has(2) // false
Object
undefined
来判断是否存在该元素。如果 o
中的确存在一个 prop
属性,而且该属性值正好为 undefined
,就会出现不一样的结果。
const o = {}
o.prop === undefined // true
o.prop = undefined
o.prop === undefined // true
in
操作来判断。in
操作会沿着继承链寻找属性,当属性存在于继承链上,而不存在于对象自身时,in
操作也能得到 true
的结果。
const o = {}
'prop' in o // false
o.prop = 'someValue'
'prop' in o // true
const o = Object.create({ prop: 'someValue' }) 'prop' in o // true
- 使用 `hasOwnProperty()`。该方法只会在对象自身寻找是否存在某个属性。
```javascript
const o = {}
Object.prototype.hasOwnProperty.call(o, 'prop') // false
Map
delete()
来删除元素, 如果 Map
实例中存在该键并且删除成功,返回 true
,否则返回 false
。
m.delete(key)
Object
delete
来删除属性,只有当该属性是 non-configurable 的时候(configurable: false
),返回 false
,其他情况都返回 true
,包括成功删除属性或者对象根本没有该属性。use strict
的时候尝试删除一个 non-configurable 属性会抛出异常。Object
可能是个更好的选择,毕竟字面量创建一个对象比构造函数创建一个 map
更高效,对象访问属性比 map
获取键值对更高效(?)。Map
仅仅是一个哈希表,而 Object
有更多的内在逻辑,当需要频繁增删键值对的时候,Map
有更高的效率。Map
在存储大型数据时表现更好,特别是当键名在运行时才确定,当所有键是相同类型所有值是相同类型
1. 什么是 Map
Map
是一种存储键值对的数据集合类型,每一对键值对都能从唯一的键映射到对应的值,所以Map
中不存在重复的键值对。1.1
new Map()
Map
通过调用构造函数的方式来创建一个Map
实例,以下代码创建了一个空Map
实例,使用set
方法关联键值对,使用get
方法获取键对应的值。该构造函数接受一个
[[key, value], ...]
形式的二维数组或者其他可迭代对象作为参数。1.2 迭代 Map
可以使用
for..of
以及forEach
来迭代Map
实例可以使用
typeof <obj>[Symbol.iterator] === 'function'
来判断是否为可迭代对象1.3 Map 的键
Map
的键可以是任意的数据类型,在使用set
方法取值的时候Map
根据===
的运算结果来判断应该取哪个值。但是有一个特例是NaN
,虽然NaN !== NaN
,但是对于Map
来说,NaN
与其自身相等。