Because, remember, arrays are just objects with some syntactic sugar to make it look like they have sequential indicies. So the
.length method actually just returns the largest index plus one:
There may have been a use-case for this
.length method that made it a beautiful idea. But that use-case is not immediately obvious on inspection.
To be sure, people have come up with all kinds of tricks to get around this. Casting the object to JSON and looking for square brackets usually works. But what if the Array was created in a different window? The only test I have found that works cross-browser and cross-window is pretty inefficient:
I prefer to know the exact state of the objects I am workign with ahead of time. Which we can do by creating our own array initializer:
The default sorting method on Arrays does not sort numbers correctly:
Seriously, it would have take like an hour to do a type check on the default
sort method and use slightly different logic. But, no, the default method converts everything to Strings before sorting them. And here we are. Luckily, we can pass our own sorting function to this method, to fix a mistake that should have been fixed 20-some years ago:
.substring() method does the exact same as the
.slice() method, expect that it does not accept negative values.
It was redundant and useless 20 years ago, and still is.
Another feature that undoubtedly came from a desire to help beginners is the automatic inject of semicolons. This has caused me problems in the past, but has never saved me any. Particularly because of outlying cases that different browsers try and treat differently. The classic bad example is this code:
Notice that this version, with the automatically inserted semicolon, has unreachable code after the return statement.
arguments await* break case catch class* const continue debugger default delete do else enum* eval export* extends* false finally for function if implements import* in instanceof interface let* new null package private protected public return static super* switch this throw true try typeof var void while with yield
Keywords marked with
* were useless, but are now used in ECMAScript 5/6.
And here is the offending list of keywords that have never been used in the language:
abstract boolean byte char double final float goto int long native short synchronized throws transient volatile
I should mention here that ECMAScript 5 and 6 actually removes all of the above unused reserved words. Sadly, a lot of people still use Internet Explorer, so we are not in an ECMAScript 5 world yet.
typeof operator is supposed to return a string that describes the type of an object.
But there are many examples of completely counter-intuitive behaivor:
Unlike in most languages, I tend not to trust or use the
parseInt function is supposed to take in a string, and if possible, convert it to an integer:
The problem is that if you pass it a string that starts with some numbers, it will parse the leading characters and drop the rest; silently. We need some way to be notified when this edge case occurs.
NaN in predicate statements is mind-boggling:
The usual boolean operators (
These operators area also a hot mess in a lot of other ways:
The list goes on and on.
The only solution is to use
void is an operator that takes in a value and returns
undefined. Which, yes, is exactly as useless as it sounds.