Map.prototype.has()
The clean existence check that objects never quite managed. There is no prototype to confuse it, no hasOwnProperty to be shadowed, and no __proto__ hazard.
Demo
A key holding null or undefined still counts as present — existence and value are separate questions here, which is exactly what get cannot tell you. The last two cases are where Map beats an object outright: 'toString' and '__proto__' are not special. On a plain object, 'toString' in obj is true before you set anything, and assigning __proto__ can replace the prototype. A Map has no prototype chain for its entries, so both are simply absent keys.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| key | any | yes | The key to test, matched by SameValueZero. NaN is found; 0 and -0 are the same key. |
Return value
boolean — True if an entry with that key exists, whatever its value. Unaffected by the prototype chain, because a Map has no inherited entries.
Common patterns
if (!map.has(id)) return notFound();
const counts = new Map(); counts.set(userInput, 1);
if (!m.has(k)) m.set(k, []); m.get(k).push(x);
Examples
Pitfalls
new Map([[1, "x"]]).has("1")
new Map([[1, "x"]]).has(Number("1"))
const m = new Map([["a", 1]]); "a" in m
m.has("a")
new Map([[{id: 1}, "x"]]).has({id: 1})
const k = {id: 1}; new Map([[k, "x"]]).has(k)
if (m.has(k)) use(m.get(k));
const v = m.get(k); if (v !== undefined) use(v);
When to use
- Testing existence when values may be undefined or null
- Dictionaries keyed by untrusted strings, where object keys would be unsafe
- The get-or-create accumulator pattern
- Replacing Object.hasOwn on data that is really a keyed collection
- You need the value anyway → get, and check the result
- Keys are a fixed set of known strings → an object is simpler
- You want to know about inherited properties → that concept does not apply here
Notes
FAQ
Because a Map has no prototype chain for its entries. On an object you must use Object.hasOwn to avoid inherited properties, and a key named __proto__ can replace the prototype instead of storing a value. A Map treats every key as ordinary data.
new Map().has("toString"); // false "toString" in {}; // true