请查看以下代码段:
class Node {
constructor(num) {
this.num = num;
this.right = null;
this.left = null;
}
}
let node1 = new Node(1);
let node2 = new Node(2);
let hash = {};
hash[node1] = 1;
console.log(hash[node2]); // prints "1" ????
为什么hash [node2]返回值1? 哈希中仅存储了node1 ...
答案 0 :(得分:3)
如果您记录对象,则会得到以下信息:
{ '[object Object]': 1 }
为什么下面的记录为1,因为node2被解释为[object Object]
console.log(hash[node2]); //This is evaluating hash['object Object'] (Again)
要解决此问题,有多种方法,一种方法是使用JSON API对对象进行字符串化,然后将返回值用作键。
例如
hash[JSON.stringify(node1)] = 1;
现在您拥有的是:
{'{"num":1,"right":null,"left":null}': 1 }
因此,按预期方式,现在将无法访问hash [node2]。
hash[node2] === undefined; //true
hash[JSON.stringify(node2)] === undefined; //true
您可能想为此创建一个小的API。作为一个非常粗糙的例子:
class Hash {
constructor () {
this.hashes = {};
}
get (key) {
return this.hashes[JSON.stringify(key)];
}
set (key, value) {
this.hashes[JSON.stringify(key)] = value;
}
}
const hashStore = new Hash();
hashStore.set({foo: 'bar'}, 1);
hashStore.set({foo: 'cheese'}, 2);
console.log(hashStore.get({foo: 'bar'})); // 1
console.log(hashStore.get({foo: 'cheese'})); //2
或者,如果您仅使用对象作为“您的控制”中的键,那么正如Jakub Keller在其答案中指出的那样,您可以覆盖Node类的toString函数。
这两种方法的后遗症都是“唯一性”,要使这两种方法成为稳定的方法,您都希望为每个对象引入一个唯一键,如果您使用Jakub Keller的方法,则应使用该唯一键在toString重写中。
这两种方法都可以满足一组需求,如果您要存储文字,作为键的一组不同对象,我可能会采用我的方法,并让API在存储的每个对象上写入一个自定义的唯一ID在get方法中,它还是不完美的,因为您可能会覆盖现有密钥。
答案 1 :(得分:2)
该值显示为1
,因为任何一个对象的哈希在技术上都是[object Object]
。因此,您的密钥是[object Object]
。
尝试覆盖Node类的toString
并通过调用toString
进行显式转换:
class Node {
constructor(num) {
this.num = num;
this.right = null;
this.left = null;
}
toString() {
return this.num;
}
}
let node1 = new Node(1);
let node2 = new Node(2);
let hash = {};
hash[node1] = 1;
console.log(hash[node2.toString()]);
// output: 2
答案 2 :(得分:0)
您可以像这样在哈希对象上使用Object.assign()方法:
hash = Object.assign({node1, node2}, {});