简体   繁体   English

Map.has 与 Map.get 之间的性能差异

[英]Performance difference between Map.has vs Map.get

Is there any advantage to use Map.has() for checking if key exists in Map instead of using Map.get() ?使用Map.has()来检查Map中是否存在密钥而不是使用Map.get()有什么好处吗? (Other than code readability reasons) (代码可读性原因除外)

I checked ES2015 language specifications and both methods seems the same except the return value so I believe the performance is the same but maybe there are some other aspects I don't know of that could affect performance here.我检查了 ES2015 语言规范,除了返回值外,这两种方法看起来都一样,所以我相信性能是一样的,但也许还有一些我不知道的其他方面会影响这里的性能。

Map.prototype.has ( key ) Map.prototype.has(钥匙)

The following steps are taken:采取以下步骤:

Let M be the this value.令 M 为 this 值。 If Type(M) is not Object, throw a TypeError exception.如果 Type(M) 不是 Object,则抛出 TypeError 异常。 If M does not have a [[MapData]] internal slot, throw a TypeError exception.如果 M 没有 [[MapData]] 内部槽,则抛出 TypeError 异常。 Let entries be the List that is the value of M's [[MapData]] internal slot.设条目为 M 的 [[MapData]] 内部槽值的列表。 Repeat for each Record {[[key]], [[value]]} p that is an element of entries, If p.[[key]] is not empty and SameValueZero(p.[[key]], key) is true, return true.对作为条目元素的每个 Record {[[key]], [[value]]} p 重复,如果 p.[[key]] 不为空且 SameValueZero(p.[[key]], key) 为真,返回真。 Return false.返回假。

Map.prototype.has method specification Map.prototype.has方法规范

Map.prototype.get ( key ) Map.prototype.get(密钥)

The following steps are taken:采取以下步骤:

Let M be the this value.令 M 为 this 值。 If Type(M) is not Object, throw a TypeError exception.如果 Type(M) 不是 Object,则抛出 TypeError 异常。 If M does not have a [[MapData]] internal slot, throw a TypeError exception.如果 M 没有 [[MapData]] 内部槽,则抛出 TypeError 异常。 Let entries be the List that is the value of M's [[MapData]] internal slot.设条目为 M 的 [[MapData]] 内部槽值的列表。 Repeat for each Record {[[key]], [[value]]} p that is an element of entries, If p.[[key]] is not empty and SameValueZero(p.[[key]], key) is true, return p.[[value]].对作为条目元素的每个 Record {[[key]], [[value]]} p 重复,如果 p.[[key]] 不为空且 SameValueZero(p.[[key]], key) 为真,返回 p.[[value]]。 Return undefined.返回未定义。

Map.prototype.get method specification Map.prototype.get方法规范

One reason why Map.has could be preferable would be if the key happens to exist, but the value is falsey. 之所以可以选择Map.has原因之一是,如果密钥恰好存在,但该值是假的。 If you use Map.get , you'll also have to check whether the value === undefined (and even that does not guarantee that the key does not exist - the key may exist, but have a value of undefined ): 如果使用Map.get ,还必须检查=== undefined的值(甚至不能保证该键不存在-该键可能存在,但是值undefined ):

 // Not good enough: const map = new Map(); map.set('foo', 0); if (map.get('foo')) { console.log('Map has "foo" key'); } 

 // Better, but not foolproof: const map = new Map(); map.set('foo', 0); map.set('bar', undefined); const valAtFoo = map.get('foo'); if (valAtFoo !== undefined) { console.log('Map has "foo" key'); } // Incorrect: const valAtBar = map.get('bar'); if (valAtBar !== undefined) { console.log('Map has "bar" key'); } 

 // Solution: use map.has instead of map.get const map = new Map(); map.set('foo', 0); map.set('bar', undefined); if (map.has('foo')) { console.log('Map has "foo" key'); } if (map.has('bar')) { console.log('Map has "bar" key'); } 

You would use Map.has for the same reason that you would use Object.prototype.hasOwnProperty for checking whether an object has a certain property - using obj[prop] to check if the prop exists just isn't good enough in certain cases. 使用Map.has的原因与使用Object.prototype.hasOwnProperty来检查对象是否具有特定属性的原因相同-在某些情况下使用obj[prop]检查prop存在是不够的。

It's not an issue of performance - rather, it's because in some cases, there's just no other way . 这不是性能问题,而是因为在某些情况下别无选择 ( .has is also more readable, though you said to ignore that part) .has也更具可读性,尽管您说过忽略了该部分)

Let's say we're storing Objects into a Map:假设我们将对象存储到 Map 中:

const myMap = new Map(/* collection of objects */);`

In code samples, we can ofen see this:在代码示例中,我们经常可以看到:

function search(key) {
    if (myMap.has(key)) return null;
    let obj = myMap.get(key);
    return obj;
}

In case the key exists in the Map, we're searching for it 2 times: .has() then.get() !如果密钥存在于 Map 中,我们将搜索它 2 次: .has() then.get() !

The function can be optimized this way: function 可以这样优化:

function search(key) {
    const obj = myMap.get(key);
    return obj || null;
}

But what if, instead of Objects we're storing primitive values?但是,如果我们存储的不是对象而是原始值呢?

If the key exists, but its associated value is falsy (zero, false, empty string...), the last line will return null !如果键存在,但其关联值为假(零、假、空字符串...),最后一行将返回 null !

Of course, we could do this: return obj?== undefined: obj : null当然,我们可以这样做: return obj?== undefined: obj : null

But we're lazy programmers, so let's use the nullish coalescing operator??但是我们是懒惰的程序员,所以让我们使用 nullish 合并运算符吧??

function search(key) {
    const value = myMap.get(key);
    return value ?? null;
}

This will do the trick, wether we're dealing with Objects or primitive values:-)无论我们处理的是对象还是原始值,这都可以解决问题:-)

Personnally, I never use the Map.prototype.has() method.就个人而言,我从不使用 Map.prototype.has() 方法。 Do you know examples where it could be useful?你知道它可能有用的例子吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM