The answer, of course, is no. But why create the confusion in the first place? It turns out this was a ploy made by the handsomest guys in the Netscape marketing department in 1995. The moral here is: never let marketing make any important decisions.
Then some clever bloke decided to add the
new keyword to the language. The
new keyword uses the
prototype object on a given function and constructs a new object from it. And, of course, it allows for some extra logic at instantiation so that an object can be configured. This is an interesting and useful idea.
However, every function has a
prototype object. And there is no way to tell at run time which functions are constructors. This ambiguity can lead to bugs. Many people have designed ways around this problem (“The first letter of a constructor label is capital!”), it seems safer to just not use
You would be forgiven if you thought that the
.length method on an array would return the number of elements in the array. And, indeed, it can sometimes look like that:
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.
Array vs Object
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.
To Be Continued?