@title Javascript Pitfalls @group flavortext This document discusses pitfalls and flaws in the Javascript language, and how to avoid, work around, or at least understand them. = Implicit Semicolons = Javascript tries to insert semicolons if you forgot them. This is a pretty horrible idea. Notably, it can mask syntax errors by transforming subexpressions on their own lines into statements with no effect: lang=js string = "Here is a fairly long string that does not fit on one " "line. Note that I forgot the string concatenation operators " "so this will compile and execute with the wrong behavior. "; Here's what ECMA262 says about this: When, as the program is parsed ..., a token ... is encountered that is not allowed by any production of the grammar, then a semicolon is automatically inserted before the offending token if one or more of the following conditions is true: ... To protect yourself against this "feature", don't use it. Always explicitly insert semicolons after each statement. You should also prefer to break lines in places where insertion of a semicolon would not make the unparseable parseable, usually after operators. = ##with## is Bad News = ##with## is a pretty bad feature, for this reason among others: with (object) { property = 3; // Might be on object, might be on window: who knows. } Avoid ##with##. = ##arguments## is not an Array = You can convert ##arguments## to an array using JX.$A() or similar. Note that you can pass ##arguments## to Function.prototype.apply() without converting it. = Object, Array, and iteration are needlessly hard = There is essentially only one reasonable, consistent way to use these primitives but it is not obvious. Navigate these troubled waters with @{article:Javascript Object and Array}. = typeof null == "object" = This statement is true in Javascript: typeof null == 'object' This is pretty much a bug in the language that can never be fixed now. = Number, String, and Boolean objects = Like Java, Javascript has primitive versions of number, string, and boolean, and object versions. In Java, there's some argument for this distinction. In Javascript, it's pretty much completely worthless and the behavior of these objects is wrong. String and Boolean in particular are essentially unusable: lang=js "pancake" == "pancake"; // true new String("pancake") == new String("pancake"); // false var b = new Boolean(false); b; // Shows 'false' in console. !b; // ALSO shows 'false' in console. !b == b; // So this is true! !!b == !b // Negate both sides and it's false! FUCK! if (b) { // Better fucking believe this will get executed. } There is no advantage to using the object forms (the primitive forms behave like objects and can have methods and properties, and inherit from Array.prototype, Number.prototype, etc.) and their logical behavior is at best absurd and at worst strictly wrong. **Never use** ##new Number()##, ##new String()## or ##new Boolean()## unless your Javascript is God Tier and you are absolutely sure you know what you are doing.