尝试使用对象作为键加载哈希时出现意外行为;也就是说,当稍后检索我的数据时,散列总是引用最后使用的密钥。我希望这是由于闭包的行为,然而,我认为我已经做了必要的事情来防止这种情况:
var hash = {};
var arry = [];
var list = [{val:"a"},{val:"b"},{val:"c"}];
var len = list.length;
dump("load : \n");
for (var i=0;i<len;i++) {
let pos = i;
let obj = list[pos];
hash[obj] = obj.val;
arry.push(obj);
dump(" "+obj.val+" "+hash[obj]+"\n");
}
dump("retrieve : \n");
for (var i=0;i<len;i++) {
let pos = i;
let obj = list[pos];
dump(" "+obj.val+" "+arry[pos].val+" "+hash[obj]+"\n");
}
输出是:
load :
a a
b b
c c
retrieve :
a a c
b b c
c c c
我故意通过使用let来提高迭代对象的范围来试图阻止这种情况,但我显然遗漏了一些东西。我想了解这背后的原因,以及如何使用Javascript来防止它。
答案 0 :(得分:6)
Object keys in JavaScript can only be strings.这意味着如果你传递的东西不是字符串,它会被转换为字符串。由于您正在使用不“覆盖”Object.toString
的对象,因此它们都具有相同的字符串表示形式(它是"[object Object]"
),这就是散列始终引用最后使用的密钥的原因。
更多信息:Strange equality issue with Javascript object properties
答案 1 :(得分:0)
您可以使用JSON.stringify
来标记对象。
var a = {};
a.b = 1;
JSON.stringify(a);
// '{"b": 1}'
注意:您无法对循环对象进行字符串化:
var a = {};
a.a = a;
JSON.stringify(a);
// TypeError: Converting circular structure to JSON