Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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()? (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.

Map.prototype.has ( key )

The following steps are taken:

Let M be the this value. If Type(M) is not Object, throw a TypeError exception. If M does not have a [[MapData]] internal slot, throw a TypeError exception. Let entries be the List that is the value of M’s [[MapData]] internal slot. 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. Return false.

Map.prototype.has method specification

Map.prototype.get ( key )

The following steps are taken:

Let M be the this value. If Type(M) is not Object, throw a TypeError exception. If M does not have a [[MapData]] internal slot, throw a TypeError exception. Let entries be the List that is the value of M’s [[MapData]] internal slot. 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]]. Return undefined.

Map.prototype.get method specification

like image 487
Avi L Avatar asked Sep 12 '25 18:09

Avi L


1 Answers

One reason why Map.has could be preferable would be if the key happens to exist, but the value is falsey. 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):

// 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.

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)

like image 79
CertainPerformance Avatar answered Sep 15 '25 09:09

CertainPerformance