【发布时间】:2014-09-15 00:44:43
【问题描述】:
我需要从 JavaScript 对象生成校验和。
不幸的是,由于 JavaScript 的对象排序,似乎没有一种简单的方法可以实现这一点。例如,拿这些对象:
var obj1 = {type:"cake",quantity:0}
, obj2 = {quantity:0,type:"cake"};
我认为这些对象的数据相同,并且希望它们的校验和相同。我真的不在乎对象的顺序,只要它们中的数据相同即可。
唉,两者的JSON.stringify其实是不相等的;因为对对象进行校验和的唯一方法是通过它的字符串表示,并且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 操作系统中)浏览器,您可以在这里自己检查:http://jsperf.com/sort-then-json-stringify-vs-smarter-stringify),当然它使两个 Object String 表示相等!
但是,我只是想知道我是否遗漏了一些东西,并且一直以来都有一个内置方法可以解决这样的问题串联。 我宁愿不这样做。
【问题讨论】:
-
您不应该使用
for ... in循环来遍历 JavaScript 中的数组。使用带有索引变量的普通for循环或使用.forEach()。 -
您的对象中的所有属性值都是简单值还是其中一些可以是对象或数组(例如嵌套结构)?
-
@jfriend00 我本来打算在里面放另一个对象,但这不是必需品
-
这只是意味着您必须检查每个值的类型并决定是否还需要扩展它。它只是添加了更多代码,但肯定是可行的。
标签: javascript json checksum adler32