19

深い比較とJSONシリアル化可能なオブジェクトのコピーのためにいくつかの実装を試みた後、私は多くの場合、最速であることに気づきました。

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

でも、これは浮気しているような気がします。私が将来私を悩ませるいくつかの問題を見つけるように。それらを使用しても大丈夫ですか?

4

4 に答える 4

26

JavaScriptはキーの順序を保証しません。

それらが同じ順序で入力された場合、このアプローチはほとんどの場合機能しますが、信頼性は高くありません。

また、完全に等しいが、キーが異なる順序で入力されたオブジェクトの場合はfalseを返します。

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

JSON.stringify({ b: 2, a: 1}) === "{"b":2,"a":1}"
于 2014-09-27T17:53:36.840 に答える
14

古い質問だと思いますが、答えにもう少し追加したかったのです。そうしないと、誰かがこのページから離れて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}

これらは、注文が問題ではない場合でも問題を引き起こす可能性のある癖です(他の人が言っているように、問題になる可能性があります)。ほとんどの場合、これらの癖が醜い頭をもたげる可能性は低いですが、バグを見つけるのが非常に困難になる可能性があるため、注意しておくことをお勧めします。

于 2016-03-15T13:03:35.120 に答える
0

この関数は、オブジェクトの配列または値を詳細に比較するために作成しました。必要に応じて使用してください:)オブジェクトと配列のエントリ順序がランダム化された非常に膨大なオブジェクトのサンプルでテストしました。

function c(x,y) {
    if(!x&&!y)return!0;if(!x||!y)return!1;if(typeof(x)
    !=typeof(y))return!1;if(x instanceof Array){if(
    x.length!=y.length)return!1;var f=[];for(var i=0;
    i<x.length;i++){if(!c(x[i],y[i]))f.push(i)}var g=
    [...f];for(const i of f){let r=!1;for(const j of g){if(
    c(x[i],y[j])){g.splice(g.indexOf(j),1);r++;break}}if(!r)
    return!1}return!0}else if(x instanceof Object){var e1=
    Object.entries(x);try{return c(e1,r(Object.entries(y),
    e1))}catch(e){return!1}}else{return x===y}function r(
    u,v){var a=[];if(u.length!=v.length)return u;for(
    var i=0;i<v.length;i++){a.push(m(u,v[i][0]))}return a}
    function m(a,k){for(var i=0;i<a.length;i++){
    if(a[i][0]===k)return[a[i][0],a[i][1]]}throw 0;}
}
于 2022-02-04T14:26:09.610 に答える
-1

キーと値のペアが常に同じ順序である限り、はい、stringifyを使用して、deep equals演算子(===)を使用して比較できます。

于 2013-03-13T02:59:26.297 に答える