Even if materials_1
and materials_2
contain the same string
values, they are actually two different Arrays
. When you compare them, you are actually comparing references, that's why something like that will always be false
, regardless of the content of the Arrays.
The same applies for [] == []
. Each []
creates a new empty array and then you compare the references to them.
However, when you compare them to materials_3
, which is a string
(using ==
), JS will call valueOf()
on the other arrays to convert them to their primitive value. As the value returned from valueOf()
is not a primitive either, it will call toString()
on it, which returns "Hydrogen,Helium,Lithium"
. As strings are primitives, now the comparison will be done by value and return true
.
You can find more about valueOf()
on MDN:
JavaScript calls the valueOf
method to convert an object to a primitive value. You rarely need to invoke the valueOf
method yourself; JavaScript automatically invokes it when encountering an object where a primitive value is expected.
By default, the valueOf
method is inherited by every object descended from Object
. Every built-in core object overrides this method to return an appropriate value. If an object has no primitive value, valueOf
returns the object itself.
You can see that in action here:
function ObjectWrapper(actualObject) {
this.actualObject = actualObject || {};
}
ObjectWrapper.prototype.valueOf = function() {
console.log('valueOf');
return this.actualObject; // Not a primitive.
};
ObjectWrapper.prototype.toString = function() {
console.log('toString');
return this.actualObject.toString();
};
const foo = new ObjectWrapper([1, 2, 3]);
const bar = '1,2,3';
console.log(foo == bar);