Does anybody really know why JS's type system was designed the way it was? It seems so out of whack with what people want out of a language, dynamically typed or otherwise.
It's because Eich was told to make JS C-like. In C, an empty array, an empty string, 0, false and null are all the same value: a word with all bits 0. So in JS, those are all are falsy and == to each other.
In C, empty strings are truthy, being a non-null pointer to a NUL character. Depending on what you mean by "an empty array" that might also be a non-null pointer to a zero-length region of memory, and thus also truthy in C.
"" is actually true in C, but that's also because it represents something in memory. Consider how C encodes strings: an empty string is a _pointer_ to a 0 (or a '\0', if you want to think of it as a char). However, the pointer (being an address) is non-zero (since the address 0 is NULL).