我在node.js应用程序中使用Javascript ES6功能:
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
在此代码中,我想使用一对Int
作为我的地图的关键字(allElem
)。
问题是我不知道Map
如何比较javascript中的对象
有人可以帮帮我吗?
答案 0 :(得分:4)
Map
确实使用SameValueZero algorithm来比较密钥。这意味着引用相等用于对象,因此如果您有a = new PairKey(1, 2)
和b = new PairKey(1, 2)
,则它们不是同一个对象 - a !== b
。
那么你能做些什么来解决这个问题呢?基本上有两种解决方法:
new PairKey
在使用相同参数调用时始终返回相同的对象此外,您可以将Map
子类化为覆盖所有方法的所有方法,以便他们专门处理PairKey
,依赖于上述技术之一。
不幸的是,如果没有弱引用并且没有泄漏内存,就不可能实现哈希值,所以我们不得不求助于第一种技术:
class Pair {
constructor(x, y) {
this.x = x;
this.y = y;
}
toKey() {
return `Pair(${this.x}, ${this.y})`;
}
static key(x, y) {
return new Pair(x, y).toKey();
}
}
var allElem = new Map(); // string -> string
allElem.set(Pair.key(1, 2), 'a');
allElem.set(Pair.key(2, 3), 'b');
console.log(allElem.has(Pair.key(1, 2))); // true
答案 1 :(得分:3)
您的代码失败的原因是Map使用相同值算法来匹配键。对象实例与另一个对象实例的值不同,即使两者共享相同的内在值(例如,尝试({a:1} === {a:1})
- >它是假的)。您可以使用的一种方法是向对象添加一个键属性,以便相同的内部值生成完全相同的键(1到1)。然后在设置Map条目时使用该键。请参阅示例(使用Symbol.for
生成可重现密钥):
'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));
答案 2 :(得分:0)
您的地图密钥是一个对象。 console.log
会返回false
,因为您正在创建一个新对象来检索它们的密钥。它有同一对并不重要。重要的是它是一个不同的新对象。
如果要检索与new pairKey(1,2)
对应的值,则必须执行以下操作:
let key = new pairKey(1,2);
allElem.set(key, 'a');
console.log(allElem.has(key));
换句话说,如果您使用object作为键,请确保使用相同的对象来检索值。