Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用JSON.stringify进行深度比较和克隆是否合适?_Javascript_Json_Equality_Deep Copy_Object Comparison - Fatal编程技术网

Javascript 使用JSON.stringify进行深度比较和克隆是否合适?

Javascript 使用JSON.stringify进行深度比较和克隆是否合适?,javascript,json,equality,deep-copy,object-comparison,Javascript,Json,Equality,Deep Copy,Object Comparison,在尝试了几个实现来对JSON可序列化对象进行深入比较和复制之后,我注意到最快的实现通常是: function deep_clone(a){ return JSON.parse(JSON.stringify(a)); }; function is_equal(a,b){ return JSON.stringify(a) === JSON.stringify(b); }; 不过我觉得这是作弊。就像我会发现一些未来会困扰我的问题。可以使用这些吗?只要键值对始终处于相同的顺序,是的,您可

在尝试了几个实现来对JSON可序列化对象进行深入比较和复制之后,我注意到最快的实现通常是:

function deep_clone(a){
   return JSON.parse(JSON.stringify(a));
};
function is_equal(a,b){
    return JSON.stringify(a) === JSON.stringify(b);
};

不过我觉得这是作弊。就像我会发现一些未来会困扰我的问题。可以使用这些吗?

只要键值对始终处于相同的顺序,是的,您可以使用stringify来使用deep equals操作符(==)进行比较。

JavaScript不保证键的顺序

如果它们以相同的顺序输入,这种方法在大多数情况下都会起作用,但并不可靠

此外,对于完全相等但其键以不同顺序输入的对象,它将返回false:

JSON.stringify({ a: 1, b: 2}) === "{"a":1,"b":2}"

JSON.stringify({ b: 2, a: 1}) === "{"b":2,"a":1}"

我意识到这是一个老问题,但我只是想补充一点答案,因为有人可能会离开本页,错误地认为使用
JSON.stringify
进行比较/克隆是可行的,只要它不用于比较/克隆成员无序的对象。(公平地说,对于公认的答案,他们不应该离开,认为这样做;它说,“如果[成员]以相同的顺序输入,这种方法在大多数情况下都会起作用。”)

代码可能最能说明潜在的问题:

JSON.stringify(NaN) === JSON.stringify(null)
// => true

JSON.stringify(Infinity) === JSON.stringify(null)
// => true

// or, to put it all together:
JSON.stringify({ val1: (1 / 0), val2: parseInt("hi there"), val3: NaN }) === JSON.stringify({ val1: NaN, val2: null, val3: null })
// => true

// and here's the same example with "cloning" rather than comparison:
JSON.parse(JSON.stringify({ val1: (1 / 0), val2: parseInt("hi there"), val3: NaN }))
// => Object {val1: null, val2: null, val3: null}

即使订购不是问题(正如其他人所说,这可能是问题),这些怪癖也会造成麻烦。在大多数情况下,这些怪癖不太可能会出现在他们丑陋的脑袋里,但意识到它们是件好事,因为它们可能会导致一些很难找到的bug。

我只使用JSON serializable objects.FWIW文章严格要求使用“JSON object”,并声明没有“JSON object”这样的东西@BenjaminGruenbaum不完全重复,但是这些家伙还是在使用旧的JSON库。@DanC那么我怎么称呼JSON可序列化对象呢?很公平,在这种情况下没有问题。是的。这使得另一个答案是错误的。在最近的版本中,Javascript确实保证了密钥顺序。有关概述,请参见例如。实际上,JS引擎已经在这样做了。我认为既然现在定义了键顺序,两个具有不同顺序的相同键的对象不应该被视为等价的。因此,
JSON.stringify
比较有效。有人尝试过使用排序吗?类似于JSON.stringify({a:1,b:2}).split(“”.sort().join(“”===JSON.stringify({b:2,a:1}).split(“”.sort().join(“”)@wmik排序将不起作用。考虑这个例子<代码> JSON.StrugI化({a:12,b:12 }).Sead(“”)=(=)= JSON.StrugI化({B:11,A: 22 }).Seple(“”).SoTo():“连接”(“”)< /C>问题是关于“JSON可序列化对象的深度比较和复制”,因此
Infinity
NaN
和其他不属于JSON的值实际上与包含函数、
窗口
对象、
未定义的
、正则表达式等的对象没有任何关系……这是严格的等式,非深度相等运算符,您还可以使用常规相等(
=
)来比较
JSON.stringify