The first equality is simple, it's a comparison between the same object (same reference), so it returns true.
The second one is a bit tricky, so I'll try to explain better below.
TL;DR
For those who are a bit lazy, here is a simple explanation without quoting the spec every step:
[0] == ![0] => we evaluate ![0] first, which yields false(because [0] is a truthy value).
[0] == false => [0] is evaluated to [0].toString() which is "0".
"0" == false => "0" is converted to the number 0; the same is for false, so we obtain:
0 == 0 which is finally true.
Complete explanation
As for the first equality, for the sake of completeness, I quote here the interested part of the spec.
1.f Return true if x and y refer to the same object. Otherwise, return false.
So this returns true, as expected. Now the tricky part:
First of all, we have to evaluate the UnaryExpression on the right:
- Let expr be the result of evaluating UnaryExpression.
- Let oldValue be ToBoolean (GetValue(expr) ).
- If oldValue is true, return false.
- Return true.
But ToBoolean uses this algorithm, and GetValue should return either an Object or a non-empty String, so the result of the evaluation is true. Returning to our UnaryExpression, we have !true, so the result of the final evaluation is false.
So we're back at our original comparison, now we are comparing an Object against a Boolean.
7.If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
ToNumber(false) is 0, so now we are comparing Object and Number.
Back to the specs:
9.If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
Calling ToPrimitive on our array should return its [[DefaultValue]], which should be, according to this kangax's answer, the result of calling toString on the array itself, so we obtain "0".
So, back to our comparison, it has became an equality between a String and a Number.
5.If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
Calling ToNumber on our string "0" yields 0, again we are finally at a simple comparison: 0 == 0.
Final spec step:
1.c.iii If x is the same Number value as y, return true.
And here the result explained.