Search code examples
javascriptdictionaryecmascript-6

How Javascript compare key of Map


I am using Javascript ES6 features in a node.js application:

class pairKey {
constructor(x_pos, y_pos) {
    this._X = x_pos;
    this._Y = y_pos;
}

get x() {
    return this._X;
}
set x(x_pos) {
    this._X = x_pos;
}

get y() {
    return this._Y;
}
set y(y_pos) {
    this._Y = y_pos;
}


var allElem = new Map();
allElem.set(new pairKey(1,2), 'a');
allElem.set(new pairKey(2,3), 'b');

console.log(allElem.has(new pairKey(1,2))); //Should return true instead return false

In this code I want to use a pair of Int as key of my map (allElem).
The problem is that I don't know how Map compare objects in javascript.
Someone can help me?


Solution

  • The reason your code fails is that Map uses same-value algorithm to match keys. An object instance is not the same value as another object instance, even if both share the same intrinsic value (for examle, try ({a:1} === {a:1}) -> it's false). One way you could make that work for you is to add a key property to your object such that the same intrinsic values generate the exact same key (1 to 1). Then use that key when setting Map entries. See example (Utilizes Symbol.for to generate a reproducable key):

    'use strict'
    class pairKey {
      constructor(x_pos, y_pos) {
        this._X = x_pos;
        this._Y = y_pos;
      }
    
      get x() {
        return this._X;
      }
      set x(x_pos) {
        this._X = x_pos;
      }
    
      get y() {
        return this._Y;
      }
      set y(y_pos) {
        this._Y = y_pos;
      }
    
      get key() {
        return Symbol.for(`pairKey[${this.x}:${this.y}]`);
      }
    }
    var allElem = new Map();
    allElem.set(new pairKey(1, 2).key, 'a');
    allElem.set(new pairKey(2, 3).key, 'b');
    
    console.log(allElem.has(new pairKey(1, 2).key));