Search code examples
javascriptes6-map

Why does Map.has() return false for an Integer key that does exist?


I have a map that consists of several key : value pairs, and the keys are all integers (that are then of course stored as strings).

However, I can't use Map.prototype.has("1") nor Map.prototype.has(1) to confirm a key exists within the map. How do I go about doing this? I want to use the Map.prototype.has() method in order to avoid the whole 0 is false problem.

let map = new Map();
map[1] = 2;
console.log(map); //Map { 1: 2 }
console.log(map.has("1")); //false
console.log(map.has(1)); //false


Solution

  • When you do map[1] = 2; you're not setting the item in the map data structure itself, but on the underlying generic object. Therefore, you can't expect map related methods as has() and get() to return you "correct" results as the map structure is actually empty. Always set map properties with map.set().

    Also, note that Map doesn't support indexing. You can't get an item by doing map[key]. This, once again, will access a property from the underlying object. You have to use map.get() instead.

    You can see the difference by doing this:

    let testMap = new Map();
    
    testMap['prop1'] = 'prop1value';
    testMap.set('prop2', 'prop2value');
    testMap.set('prop1', 'prop1value');
    
    console.log(testMap);
    

    enter image description here

    [[Entries]] is the actual map structure, everything else is coming from the object.

    For completeness, object properties can only be strings or symbols. Map, on the other hand, support all types(including objects and functions). I am saying this because if you do:

    let testMap = new Map();
        
    testMap['1'] = 'prop1value';
    testMap[1] = 'prop2value';
    

    you actually mutate the same property('1', numeric keys are actually converted to strings). If you use the actual map structure, however:

    let testMap = new Map();
    
    testMap.set('1', 'prop1value');
    testMap.set(1, 'prop2value');
    

    You have two separate entries: '1' and 1.