views:

463

answers:

13

I'm planing on giving an introduction talk on JavaScript and in the preparation process I wondered what the top pitfalls are that rookies fall into.

I know I've had a few gotchas before I fully understood closure, but much of the strange behavior in JavaScript is not something I think about any more...

So, which pitfalls should you definitely point out to the rookies?

+10  A: 
  • Forgetting to declare variables with var
  • Misunderstanding (or not understanding) variable scope and closures
  • Trying to solve nasty compatibility problems that framework teams have already solved
Pointy
Definitely the frameworks. By all means, someone should understand JS before using one. But they should know they're there.
detly
Yeah, frameworks can be a big pitfall. This site is stuffed with questions from newbies trying to do something specific with jQuery. jQuery has a function that almost does the task, or do some of the task, but it is just too automagic to be more generally useful.
eBusiness
+4  A: 

Nine common javascript gotchas:
http://www.fitzblog.com/bid/2127/Nine-Javascript-Gotchas

bennybdbc
One of the most important ones to know on that list is that you should always pass in the radix to `parseInt(...)`, otherwise you'll get yourself into lots of trouble.
Dan Herbert
More important is to realise that Number(x) is normally better than parseInt(x,10)
Gareth
+4  A: 
  • Closures - otherwise known as lambda functions - watch out for memory leaks.
  • Browser differences, testing in both Internet Explorer and at least one other browser is a must. Functions that only work in some browsers, or work differently in different browsers should generally be avoided. If this is not possible browser specific branching is better done detecting browser features instead of browser versions. This increases the chance of the code working in future browsers and browsers that have not been tested.
  • Getting too caught up in jQuery or Ajax framework abstraction, and not knowing the underlining JS well enough to know how to fix framework issues.
  • Not knowing that JS can be used to some degree to write OOP code. In fact it can give you a very basic OOP framework with objects.
  • Case sensitivity (if you're a vb.net developer)
  • IP Protection - knowing that you can obfuscate JS, but the source code you put out there will be very easy to steal and reverse engineer. This might not even be an issue depending on the complexity of the client side app you're writing.

Can't think of any more, but hope this helps.

JL
Browser detection is evil. You should use feature detection, not browser detection.
el.pescado
@el.pescado: +1, but to be fair, sometimes you need to detect behavior, which isn't as easy as detecting features and objects.
outis
"Closures - otherwise known as lambda functions...". Not true - closures can be lambdas, but don't have to be (they can also be named functions).
fig
@el.pescado: Browser detection isn't evil, it's merely ineffective and error-prone.
Robusto
To address the comments about browser vs feature detection: This isn't incredibly hard to do. jQuery provides very good support for handling this (http://api.jquery.com/jQuery.support/). If you don't want to use jQuery, I would still recommend checking out the jQuery.support source code as it's very easy to implement on your own as needed. (http://github.com/jquery/jquery/blob/master/src/support.js)
Dan Herbert
Ineffective and error-prone === Evil
eBusiness
+13  A: 

Boolean type conversion.

''        ==   '0'           //false
0         ==   ''            //true
0         ==   '0'           //true
false     ==   'false'       //false
false     ==   '0'           //true
false     ==   undefined     //false
false     ==   null          //false
null      ==   undefined     //true
" \t\r\n" ==   0             //true

As well as the difference between null and undefined. As listed in the table above, comparing null & undefined with == returns true, but with === it returns false. This behavior makes sense once you understand that undefined is very different from a variable having a null value, and something holding the value undefined is different from something being undefined.

Dan Herbert
+2  A: 

Not a real coding pitfall, but more one of general thought:
Don't trust the things your JavaScript is doing, it might have been turned of or even monkey patched, that means never rely on client side validation. NEVER.

Ivo Wetzel
+7  A: 

Don't accidentally leave a trailing comma in an object definition literal or IE will fail and you won't notice until much later because you never use IE for development and by then it could suck figuring out what happened.

var foo = { 
    bar: "bar", 
    baz: "baz", 
};
quixoto
+1 Very recognizable this one. In arrays, IE doesn't fail directly by throwing some syntax error, but will fail when you try to use the array because the added comma makes IE think there's one more element in the array, with value `undefined`, than there actually is. So if you ever have an error because for some reason the last element in an array is `undefined`: it's a comma.
JulianR
+4  A: 

The biggest difficulties I see for the beginner are understanding execution context (i.e., what "this" means whenever and wherever it is encountered) and the prototype system of inheritance.

Robusto
+2  A: 
  • Using window.onload = init(); instead of window.onload = init;
  • Boolean equivalences (as mentioned already)
  • Closures within a loop.
  • Using for in loop variant for iterating over Arrays.
  • Not using ; because it's "optional".
  • this (just... in general :))
  • Not using var
  • Knowing that obj.ref === obj["ref"]
Matt
+2  A: 

+ to concatenate strings:

var a = '2';
var b = 3;

a * b #  6
a - b # -1
a + b #  23
Kobi
A: 

Some extreme ones: http://wtfjs.com/

Hippo
+2  A: 

The whole concept of prototyping takes some time to fully understand but here are some common pitfalls:

Forgetting to reset the constructor property after assigning a prototype object:

var Foo() = function ()
{
    this.batz = '...';
};
Foo.prototype = new Bar();
Foo.prototype.constructor = Foo;

If you forget the least line, new Foo() will actually execute Bar().

Another pitfall with prototyping is iterating over objects/arrays without filtering out the members of the prototype:

for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
        //stuff...
    }
}

The extra condition will skip any members that are inherited from the prototype of obj.

Techpriester
+1  A: 
  • Creating sites that don't work without JS
  • Using JS for things that should be done server-side
  • Using frameworks for simple tasks that don't require them
RoToRa
+3  A: 
Andy E