Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
323 views
in Technique[技术] by (71.8m points)

javascript - JavaScript中的对象比较[重复](Object comparison in JavaScript [duplicate])

What is the best way to compare objects in JavaScript?(在JavaScript中比较对象的最佳方法是什么?)

Example:(例:) var user1 = {name : "nerd", org: "dev"}; var user2 = {name : "nerd", org: "dev"}; var eq = user1 == user2; alert(eq); // gives false I know that two objects are equal if they refer to the exact same object , but is there a way to check if they have the same attributes' values?(我知道两个对象如果引用完全相同的对象则相等 ,但是有没有办法检查它们是否具有相同的属性值?) The following way works for me, but is it the only possibility?(以下方法对我有用,但这是唯一的可能性吗?) var eq = Object.toJSON(user1) == Object.toJSON(user2); alert(eq); // gives true   ask by spankmaster79 translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Unfortunately there is no perfect way, unless you use _proto_ recursively and access all non-enumerable properties, but this works in Firefox only.(不幸的是,没有完美的方法,除非您递归使用_proto_并访问所有不可枚举的属性,但这仅在Firefox中有效。)

So the best I can do is to guess usage scenarios.(因此,我能做的最好是猜测使用情况。) 1) Fast and limited.(1)快速且有限。) Works when you have simple JSON-style objects without methods and DOM nodes inside:(当您具有简单的JSON样式的对象,而内部没有方法和DOM节点时,则可以使用:) JSON.stringify(obj1) === JSON.stringify(obj2) The ORDER of the properties IS IMPORTANT, so this method will return false for following objects:(属性的ORDER重要,因此对于以下对象,此方法将返回false:) x = {a: 1, b: 2}; y = {b: 2, a: 1}; 2) Slow and more generic.(2)速度较慢,通用性更高。) Compares objects without digging into prototypes, then compares properties' projections recursively, and also compares constructors.(在不深入研究原型的情况下比较对象,然后递归比较属性的投影,还比较构造函数。) This is almost correct algorithm:(这几乎是正确的算法:) function deepCompare () { var i, l, leftChain, rightChain; function compare2Objects (x, y) { var p; // remember that NaN === NaN returns false // and isNaN(undefined) returns true if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') { return true; } // Compare primitives and functions. // Check if both arguments link to the same object. // Especially useful on the step where we compare prototypes if (x === y) { return true; } // Works in case when functions are created in constructor. // Comparing dates is a common scenario. Another built-ins? // We can even handle functions passed across iframes if ((typeof x === 'function' && typeof y === 'function') || (x instanceof Date && y instanceof Date) || (x instanceof RegExp && y instanceof RegExp) || (x instanceof String && y instanceof String) || (x instanceof Number && y instanceof Number)) { return x.toString() === y.toString(); } // At last checking prototypes as good as we can if (!(x instanceof Object && y instanceof Object)) { return false; } if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) { return false; } if (x.constructor !== y.constructor) { return false; } if (x.prototype !== y.prototype) { return false; } // Check for infinitive linking loops if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) { return false; } // Quick checking of one object being a subset of another. // todo: cache the structure of arguments[0] for performance for (p in y) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } } for (p in x) { if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { return false; } else if (typeof y[p] !== typeof x[p]) { return false; } switch (typeof (x[p])) { case 'object': case 'function': leftChain.push(x); rightChain.push(y); if (!compare2Objects (x[p], y[p])) { return false; } leftChain.pop(); rightChain.pop(); break; default: if (x[p] !== y[p]) { return false; } break; } } return true; } if (arguments.length < 1) { return true; //Die silently? Don't know how to handle such case, please help... // throw "Need two or more arguments to compare"; } for (i = 1, l = arguments.length; i < l; i++) { leftChain = []; //Todo: this can be cached rightChain = []; if (!compare2Objects(arguments[0], arguments[i])) { return false; } } return true; } Known issues (well, they have very low priority, probably you'll never notice them):(已知问题(嗯,它们的优先级很低,可能您永远不会注意到它们):) objects with different prototype structure but same projection(具有不同原型结构但投影相同的对象) functions may have identical text but refer to different closures(函数可能具有相同的文本,但是引用了不同的闭包) Tests: passes tests are from How to determine equality for two JavaScript objects?(测试:通过测试来自于如何确定两个JavaScript对象的相等性?) .(。)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...