Rules for JavaScript and mixed-type operations are quite convoluted and depend on the operation, for example for + an extremely simplified description is:
- If both are number then the arithmetic sum is performed
- If any of the two is not a number then both are converted to string and concatenation is performed
The string conversion of an object (unless you defined what to do) is just "[object Object]" and that explains the results you described in the question.
Note that this is not the whole truth... things are much more convoluted and a full description require concepts like .toValue members, special cases for Date objects and so on. Moreover things are getting more and more complex as time passes (ES6 behavior for example requires introduction of concepts like distinction between "exoticToPrim" and "OrdinaryToPrimitive").
Unfortunately I am not kidding.
In case you want to understand better pay attention when writing test programs that you cannot trust the == operator to check what the result is because the rules for that equality operator are even more convoluted (bordering total madness, actually). == in Javascript is just a bug-hiding shelter and should have no place in any code (if strangely enough you really want what it does then implement that behavior explicitly and comment on why it is needed instead of just using ==).
Always use ===.