A while ago I got the idea to write a “my experiences with JavaScript” post; unfortunately, I’ve forgotten what I was going to put in it. However, yesterday someone said approximately “I need to learn JavaScript in 3 hours, what should I know?”, and I thought of quite a few not-immediately-obvious things to point out.

General

Beware the bad tutorials.

As far as I know, Mozilla’s Core JavaScript 1.5 Reference and Core JavaScript 1.5 Guide are not bad. (I start with the former for library/standard objects info, and the latter for language syntax.)

Anything Crockford says goes.

It’s probably a good idea to use JSLint but I haven’t myself.

If you use Firefox with Firebug, or Safari, write your code to use the console object, if present; it is a very nice tool for your inevitable print-debugging, and Firebug’s version even lets you click on objects shown to inspect them.

Miscellaneous practice

Don’t ever write a busy-wait/polling/delay loop. It won’t work and it'll waste your users' time. JavaScript in the browser is an event-driven system; use setTimeout (callback once) and/or setInterval (callback repeated with specified period) as appropriate. You can write a background loop with setTimeout: function loop() { if ( termination condition ) { return; } else { ...do something... ; setTimeout(loop, 0); } }; loop();

(callback once) and/or (callback repeated with specified period) as appropriate. You can write a background loop with setTimeout: Don’t throw "foo"; but throw new Error("foo"); because that gives Firefox, at least, an opportunity to insert call stack information.

but because that gives Firefox, at least, an opportunity to insert call stack information. JavaScript has two "nothing" values: undefined , of type "undefined", and null , of type "object". undefined is returned by failed property lookups and the default return value of functions. null doesn’t show up much unless you use it, and is useful in your code for distinguishing deliberate absence from an accidental missing value (bug).

Scope

Local variables are declared with " var ", but they are scoped to the nearest enclosing function, not the nearest { block } !

", but they are scoped to the nearest enclosing function, not the nearest block ! Functions can be closures. Use this when it’s useful.

Don’t write setTimeout('foo()', delay) (because string-eval is a bad habit), write setTimeout(foo, delay) or setTimeout(function () { foo() /* for more complicated things */ }, delay) .

this

Don’t call a user-defined constructor (say, Foo), as Foo() , only new Foo() , or it will overwrite global variables instead of creating an object. ( new binds this to a new object inside the function; a regular call leaves it as the global object.)

, only , or it will overwrite global variables instead of creating an object. ( binds to a new object inside the function; a regular call leaves it as the global object.) foo.bar() is the same as (foo.bar)() , and is not the same as var x = foo.bar; x() . The former binds this inside the function to the foo object; the latter does not.

Properties and variables

for (x in y) ... does not do what you might first expect; it iterates over all properties of the object, even inherited ones.

does not do what you might first expect; it iterates over all properties of the object, even inherited ones. If you see $('foo') : That is not some magic new operator. $ is an identifier character. That expression is a function call. From what I hear, both Prototype and jQuery define functions named $ .

: That is not some magic new operator. is an identifier character. That expression is a function call. From what I hear, both Prototype and jQuery define functions named . foo.bar is exactly equivalent to foo["bar"] .

is exactly equivalent to . foo.bar returns undefined if bar is not a property of foo ; bar throws an error if bar is not a property of whatever the environment is. So if you’re doing browser feature detection, you write code like if (window.console) , not if (console) , even though window is the global object and its properties are variables.

Numbers