13 votes

When comparing two equal Booleans it returns true but not when comparing two equal objects. No Why?

In the following code the function is used Boolean to return a value. If you do a strict comparison of the result of two functions that return the same value the result is true, but if you are comparing two objects created using new Boolean the result is false.

var salidas = [ 
  Boolean(true),
  Boolean(true) === Boolean(true),
  new Boolean(true) === new Boolean(true),
]

console.log(salidas.join('\n'));

Why is it that when you compare two objects that have been created using the same code the result is false? How do you explain this to the ECMAScript 2016?


I guess that the answer is going by the following

  • Boolean(true) returns a data primitive of type boolean with value true
  • new Bolean(true) returns an object that inherits the properties of the object Boolean.
  • Each time it is called new Bolean(true) you have objects that have the same structure inherited from the object Boolean, not to be confused with the primitive Boolean.
  • By inheritance structure I refer to both objects will have properties at the least of name, however, there is something that makes them different to the two objects and hence a strict comparison of these returns false.

What is it that makes it different to the two objects that inherit properties from the same object?


Note:

As I understand it, in colloquial terms we could say that the two objects are instances of the same class, however, I'm not sure that in strict terms this is correct because JavaScript although it is an object-oriented language, up to version 6 did not implentado the handling of classes, if not that that is a typed language. In ECMAScript 2015 (version 6) has been introduced in class, see 14 ECMAScript Language: Functions and Classes for the version 2015 and 14 ECMAScript Language: Functions and Classes for version 2016.


Apparently here the key concepts to differentiate are equality and identity

By equality, we have to understand that two things are equal when these have the same values and when it comes to objects have the same properties, and these with the same values

By identity, we have to understand that two things are identical, that is to say that they are not two things, but it is the same thing, both are one and only one thing.

Two instances of an object are not identical, even if they were created virtually at the same time, are two different things.

It is worth mentioning that "pure JavaScript" does not provide unique identifiers for the objects, but any libraries or frameworks could do it.

In the ECMAScript does not I found talk of it earlier, but yes, to some extent, Equality comparisons and sameness

Note: the link above points to the English version because the Spanish language does not include references to the most recent versions of ECMAScript being the English if it does.


Related question

8voto

César Points 14430

Update

I see where you are going your question. In JavaScript objects are stored by reference, therefore, what you should be comparing are the memory positions and these are different for each instance.


Well, as I see it, the operator new instantiates an object. In my opinion it would be a mistake to consider that two instances are exactly the same. The same thing happens with other objects:

console.log(new Array() === new Array());
console.log(new Object() === new Object());

The correct way to compare the new instances is with your value:

var salidas = [ 
  Boolean(true),
  Boolean(true) === Boolean(true),
  (new Boolean(true)).valueOf() === (new Boolean(true)).valueOf(),
]

console.log(salidas.join('\n'));

3voto

Eduen Sarceño Points 1875

The error lies in the fact that Boolean(true) returns a value booleano a data primitive, nevertheless do new Boolean(true) the return value is a objeto , which envelops the data primitive true

typeof Boolean(true) // boolean
typeof new Boolean(true) // object

To compare two objects, it is usually done by reference, i.e. make

objA === objB 

Returns true yes and only yes objB a alias from objA

So if you want to compare objects based on their properties, you'll have to implement it, as in the following snippet

Object.prototype.igualA = function(obj)
{
	var _this = this // extiende el alcance
	var mismo_constructor = _this.constructor === obj.constructor

	var mismas_propiedades = function()
	{
		var propiedades = Object.getOwnPropertyNames(_this)
		for(var i in propiedades)
		{
			var propiedad = propiedades[i]
			if(_this[propiedad] !== obj[propiedad]){ return false }	
		}	
		return true
	}()

	return mismo_constructor && mismas_propiedades
}

var x = new Boolean(true)
var y = new Boolean(true)
console.log(x.igualA(y))

1voto

Abraham TS Points 472

In Javascript objects are created by reference. That means that when you do obj1 == obj2 what is being compared is the reference, or it will return true only if it is the same object, i.e., obj1 and obj2 point to the same address in memory.

To check the equality of objects of the same class, you must define a method equals(other). For example

function Person(name){
    this.name = name;

    var self = this;
    this.equals = function(other){
        return (other instanceof Person) && self.name == other.name;
    }
}

var p1 = new Person("Juan");
var p2 = new Person("Pedro");
var p3 = new Person("Juan");

alert(p1.equals(p2)); // Devuleve false
alert(p1.equals("Juan")); // Devuelve false, "Juan" no es una instancia de la clase Person, sino un string
alert(p1.equals(p3)); // Devuelve true

Prints:

false
false
true

HolaDevs.com

HolaDevs is an online community of programmers and software lovers.
You can check other people responses or create a new question if you don't find a solution

Powered by:

X