In JavaScript The equality operation includes "= =", "= = =" Congruent, the difference between the two, do not need the majority, this article we will tell how to determine whether two objects are equal? You might think that if two objects have the same properties and their properties have the same value, then the two objects are equal. So here's an example to illustrate the following:
var obj1 = { name: "Benjamin", Sex: "male"}var obj2 = { name: "Benjamin", Sex: "Male"}//outputs:falseco Nsole.log (obj1 = = obj2);//outputs:falseconsole.log (obj1 = = = Obj2);
As you can see from the example above, return false regardless of whether you use "= =" or "= = =". The main reason is that the base type String,number is compared by the value, while the object (Date,array) and the normal object are compared by the address in memory pointed to by the pointer. Take a look at the following example:
var obj1 = { name: "Benjamin", Sex: "male"};var obj2 = { name: "Benjamin", Sex: "male"};var obj3 = obj1; Outputs:trueconsole.log (obj1 = = obj3);//outputs:trueconsole.log (obj1 = = obj3);//outputs:falseconsole.log (Obj2 = = OBJ3);//outputs:falseconsole.log (obj2 = = = Obj3);
The above example returns true because the pointers to Obj1 and Ob3 point to the same address in memory. is similar to the concept of value passing and reference passing in object-oriented language (java/c++). Because, if you want to determine whether two objects are equal, you have to be clear, do you want to determine whether the properties of the two objects are the same, or whether the properties correspond to the same values, or what? If you determine whether the values of two objects are equal, you can do the following:
function isobjectvalueequal (A, B) {//Of course, we can do it with for in//Create a Rrays of property names var aprops = Object.getownpropertynames (a); var bprops = Object.getownpropertynames (b); If number of properties is different,//objects be not equivalent if (aprops.length! = bprops.length) { return false; } for (var i = 0; i < aprops.length; i++) {var propname = aprops[i]; If values of same property is not equal,//objects is not equivalent if (A[propname]!== B[propname]) {return false; }}//If We made it this far, objects//is considered equivalent return true;} var obj1 = {name: "Benjamin", Sex: "male"};var obj2 = {name: "Benjamin", Sex: "Male"};//outputs:trueconso Le.log (Isobjectvalueequal (obj1, Obj2));
As you can see, checking the object's "value equality" we basically want to iterate over each property of the object to see if they are equal. While this simple implementation applies to our example, there are many cases where it is impossible to handle. For example: 1) If one of the property values is itself an object? 2) If one of the attribute values is Nan (in JavaScript, is it equal to its own unique value?). ) 3) If the value of one property is undefined, and the other object does not have this property (and thus evaluates to indeterminate?). A powerful way to check the "value equality" of an object is to rely on a well-developed test library that covers a variety of boundary conditions. Underscore and Lo-dash have a method called _.isequal () that is used to compare well with the depth object. You can use them like this:
Outputs:trueconsole.log (_.isequal (obj1, obj2));
Finally, we enclose some source code of IsEqual in underscore:
Internal recursive comparison function for ' isequal '. var eq = function (A, B, Astack, bstack) {//identical objects is equal. ' 0 = = = 0 ', but they aren ' t identical. See the [Harmony ' Egal ' proposal] (Http://wiki.ecmascript.org/doku.php?id=harmony:egal). if (a = = b) return a!== 0 | | 1/a = = = 1/b; A Strict comparison is necessary because ' null = = Undefined '. if (a = = NULL | | b = = NULL) return a = = = B; Unwrap any wrapped objects. if (a instanceof _) a = a._wrapped; if (b instanceof _) b = b._wrapped; Compare ' [[Class]] ' names. var className = Tostring.call (a); if (ClassName!== Tostring.call (b)) return false; Switch (className) {//Strings, numbers, regular expressions, dates, and booleans is compared by value. Case ' [Object REGEXP] '://Regexps is coerced to strings for comparison (note: ' +/a/i = = '/a/i ') case ' [obj ECT String] '://Primitives and their corresponding object wrappers is EquivalenT Thus, ' 5 ' is//equivalent to ' New String ("5") '. Return ' + A = = = ' + b; Case ' [Object number] '://' NaN ' s is equivalent, but non-reflexive. Object (NaN) is equivalent to NaN if (+a!== +a) return +b!== +b; An ' Egal ' comparison are performed for the other numeric values. return +a = = = 0? 1/+a = = = 1/b: +a = = = +b; Case ' [Object Date] ': Case ' [Object Boolean] '://coerce dates and booleans to numeric primitive values. Dates is compared by their//millisecond representations. Note that invalid dates with millisecond representations//of ' NaN ' is not equivalent. return +a = = = +b; } if (typeof a! = ' object ' | | typeof b! = ' object ') return false; Assume equality for cyclic structures. The algorithm for detecting cyclic//structures are adapted from ES 5.1 sections 15.12.3, abstract operation ' JO '. var length = Astack.length; while (length--) {//Linear SearcH. Performance is inversely proportional to the number of//unique nested structures. if (astack[length] = = = a) return bstack[length] = = = B; }//Objects with different constructors is not equivalent, but ' Object ' s//from different frames is. var aCtor = a.constructor, bctor = B.constructor; if (aCtor!== bctor &&//Handle object.create (x) Cases ' constructor ' in a && ' constructor ' In B &&! (_.isfunction (actor) && actor instanceof actor && _.isfunction (bctor) && bctor instanceof B Ctor)) {return false; }//Add the first object to the stack of traversed objects. Astack.push (a); Bstack.push (b); var size, result; Recursively compare objects and arrays. if (className = = = ' [object Array] ') {//Compare Array lengths to determine if a deep comparison is necessary. size = A.length; result = Size = = = B.length; if (result) {//DeeP Compare the contents, ignoring non-numeric properties. while (size--) {if (!) ( result = EQ (a[size], b[size], Astack, Bstack))) break; }}} else {//Deep compare objects. var keys = _.keys (a), key; size = Keys.length; Ensure that both objects contain the same number of properties before comparing deep equality. result = _.keys (b). length = = size; if (result) {while (size--) {//Deep compare each member Key = Keys[size]; if (! ( result = _.has (b, key) && eq (A[key], B[key], Astack, bstack)) break; }}}//Remove the first object from the stack of traversed objects. Astack.pop (); Bstack.pop (); return result; }; Perform a deep comparison to check if the objects is equal. _.isequal = function (A, b) {return eq (A, B, [], []); };
Thank you for your reading, I hope this article is helpful to you, the lack of the text is welcome to criticize treatise.
Reprint statement:
This article title: Javascript determines whether objects are equal
This article link: http://www.zuojj.com/archives/775.html, reprint please specify transfer from benjamin-focus on front-end development and user experience
Javascript determines whether objects are equal