Why does "[] + {} === {} + []" evaluate to "true"?

    var array = ['test1', 'test2', 'test3']
    var emptyObject = {}

    console.log(typeof(array+emptyObject));
    console.log(array+emptyObject);
    console.log(emptyObject+array);
    console.log(array+emptyObject === emptyObject+array);

    var array = [];
    var emptyObject = {}

    console.log(typeof(array+emptyObject));
    console.log(array+emptyObject);
    console.log(emptyObject+array);
    console.log(array+emptyObject === emptyObject+array);

    var array = ['firstArrayElement', 'secondArrayElement'];
    var object = {a:1, b:2}
    
    console.log(typeof(array+object));
    console.log(array+object);
    console.log(object+array);
    console.log(array+object === object+array);

    console.log(['a','b']+['c','d']);

When you convert an empty array to string you will receive empty string.

When you convert an object({}) to string you will always receive string: "[object Object]".

Plus operator is not defined for arrays and objects so JS always convert array and object to string when you use plus operator.


The second point in this magnificent answer explains what happens when you "add together" an array and an object.

var result = [] + {};

console.log(result);
console.log(typeof result);

What you get is the string [object Object] because each of the arguments is converted to a string. For an array, that results in calling .join() on it, which in turn, results in an empty string. For Objects, it produces the string "[object Object]" - adding them together leaves the second string.

The same happens on both sides of the comparison - on the right hand side, the order is different but that does not matter. The result will not be the same as point 3 in the answer, for the difference is that there {} + [] is in the beginning of the line, so {} is interpreted as an empty block. In this situation it will (correctly) be interpreted as a plain object notation). The same casting logic will be performed and it will produce the same string as before: "[object Object]"

So, in the end, you are comparing "[object Object]" === "[object Object]" which returns true.

Note that {} + [] === [] + {} will not produce the same - again, due to point 3 of the linked answer - the first {} will be interpreted as an empty block, so the left hand side becomes +[] which converts the array to a number, hence the result of the comparison will be false. However if you test this expression in the Chrome dev tools you will indeed get true. This is because Chrome will auto-wrap your expression in parentheses which forces the initial {} to be interpreted as an object. Checking {} + [] === [] + {} in Firefox or Node REPL or others should produce the "correct" false.

Tags:

Javascript