我需要从 JavaScript 对象进行校验和。
不幸的是,由于 JavaScript 的对象排序,似乎没有一种简单的方法可以实现这一点。例如,采取这些对象:
var obj1 = {type:"cake",quantity:0}
, obj2 = {quantity:0,type:"cake"};
我认为这些对象的数据相等,并希望它们的校验和相同。只要对象中的数据相同,我真的不在乎对象的顺序。
唉,JSON.stringify
这两者实际上并不相等;由于对 Object 进行校验和的唯一方法是通过其 String 表示,并且JSON.stringify
-ed 表示不相等,因此我的校验和将不相等!
我想出的一种解决方案是根据预定义的模式重新创建对象,如下所示:
var schema = ["type","quantity"];
function sortify(obj,schema){
var n={};
for(i in schema)
n[schema[i]]=obj[schema[i]];
return n
}
运行JSON.stringify(sortify(obj1,schema))==JSON.stringify(sortify(obj2,schema))
将返回true
......但代价是创建一个新对象并在数据周围洗牌。
我的另一个解决方案是将该JSON.stringify
方法替换为从预定义模式中选择键并将它们的值字符串化,然后将它们连接在一起的方法。函数内容如下:
function smarterStringify(obj,schema){
var s="";
for(i in schema)
s+=JSON.stringify(obj[schema[i]]);
return s
}
忽略这个方法没有返回正确的 JSON 的事实(它作为我正在尝试做的一个例子已经足够接近),它在速度上比第一个方法有了很大的改进(至少在我的 Chrome OS 浏览器中,你可以在这里自己检查:http: //jsperf.com/sort-then-json-stringify-vs-smarter-stringify),当然它使两个对象字符串表示相等!
然而,我只是想知道我是否遗漏了一些东西,并且有一个内置的方法来处理这样的事情,它没有 a) 将 JavaScript GC 驱动到一个病态的情况下,或者 b) 做了太多的字符串连接。我宁愿不做那些。