Archive for the ‘javascript’ Category

Different ways of defining functions in JavaScript (this is madness!)

Friday, June 24th, 2011

This is madness! This… is… JavaScript!

In JavaScript, there’s many different ways of doing something. This is both a good thing and a bad thing. To the newcomer this is definitely a bad thing, as it means not only more things to learn, but more little caveats and more places to go wrong. And so it is with declaring functions!

The aim of this is just an accessible tour of the landscape, just so you know what’s out there and what the basic differences are. Do be sure to check out the “further reading” section as well! Much of this is based on Juriy “kangax” Zaytsev’s article, which goes into more depth. But I found that there wasn’t just one reference to show all the different variable declarations.

How about ways to execute functions? That opens up another can of worms, and incidentally opens up the possibility for a future post on that topic. :)

Overview: different ways of declaring functions

function A(){};             // function declaration
var B = function(){};       // function expression
var C = (function(){});     // function expression with grouping operators
var D = function foo(){};   // named function expression
var E = (function(){        // immediately-invoked function expression (IIFE) that returns a function
  return function(){}
})();
var F = new Function();     // Function constructor
var G = new function(){};   // special case: object constructor

Function declarations: function A(){};

Function declarations are probably the most familiar and oldest way of doing things in JavaScript land. This creates a variable A which is accessible in the current scope. Scope is a separate topic, so we’ll do everything in the global scope for all these examples (something you want to avoid usually).

1. Hoisting

The interesting thing about these is that they are “hoisted” to the top of their scope, which means this code:

A();
function A(){
  console.log('foo');
};

Gets executed as this code:

function A(){
  console.log('foo');
};
A();

Which practically means that, yes, you can call the functions before they’re written in your code. It won’t matter, because the entire function gets hoisted to the top of its containing scope. (This is contrasted with variables, which only have their declaration hoisted, not their contents, as we’ll see in the next section).

2. No function declarations in If statements (or loops, etc)

You can’t define functions this way in expressions, for example if statements, which is common if we want to define different versions of a function for different circumstances, usually to address browser inconsistencies. Well, you can in some implementations, but the way the code is processed is inconsistent (kangax has documented the inconsistencies here). If you want to use this pattern, use function expressions instead.

3. Functions declarations must have names

This method doesn’t allow you to create anonymous functions, meaning that you always have to give it an identifier (in this case we’ve used “A”).

Function expressions: var B = function(){};

A function expression looks similar to function declarations, except that the function is assigned to a variable name. Though functions are not primitive values in JavaScript, this is the way they can be utilized to their full effect in this functional language. Functions are “first class“:

“[JavaScript] supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures”

1. Anonymous functions (they don’t need names)

The function name is optional in function expressions, and we call these anonymous. Here we’re setting the variable B equal to an anonymous function:

var B = function(){};

2. Variable declaration hoisting

Variable declarations are hoisted to the top of their scope, somewhat similarly to function hoisting except the contents of the variable are not hoisted as well. This happens with all variables, and it means it’s now happening with our functions, now that we’re assigning them to variables.

This code:

var A = function(){};
var B = function(){};
var C = function(){};

Will be executed as this:

var A, B, C;  // variable declarations are hoisted
A = function(){};
B = function(){};
C = function(){};

Therefore the order of setting and calling this type of function is important:

// this works
var B = function(){};
B();

// this doesn't work
B2();  // TypeError (B2 is undefined)
var B2 = function(){};

The second example gives us an error because only the variable B2′s declaration is hoisted, but not its definition, thus the “undefined” error.

Function expressions with grouping operators: var C = (function(){});

These really aren’t different from plain old function expressions and aren’t really seen in the wild (so maybe they’re just good for JavaScript quizzes?). Recently this way of declaring functions was brought up in this article and confused some folks including myself.

Here’s a good way to see what’s happening:

function(){};  // SyntaxError
(function(){});

Why does one work and the other doesn’t? The first example is a function declaration, and we learned above that we can’t declare them anonymously – that is, they must have a name. That’s why we’re getting the syntax error.

The second example is using parenthesis – grouping operators – and is therefore evaluated differently, as a function expression. The grouping operators are the things we use to help show what should be evaluated first, as in mathematical problems. We’re saying “evaluate this first, then take the result and do something with it”:

(1 + 2) * 3;  // 9
1 + (2 * 3);  // 7

In the first example we’re saying “first add 1 and 2, then take the result and multiply by 3″, whereas in the second example we’re saying “first multiply 2 and 3, then take the result and add 1″.

Because functions are first class, we can use similar grouping operators. Here’s a facetious example, but it shows how we can essentially drop in a function in the same way:

(function(){} + 1);  // function(){}1

The result is a string (because toString is being called on the function, then added/appended with 1), but you get the idea I hope.

When the JavaScript engine encounters the opening parenthesis here, we’re essentially saying “ok, start grouping this together with something else”. Using our technical terms, we’re telling the engine that we’re not making a function declaration, but instead a function expression. And then we can assign the result to a variable:

(function(){});           // resulting function not assigned
var foo = (function(){}); // resulting function assigned to foo
var bar = function(){};   // resulting function assigned to bar

Here we can see that foo and bar are really just the same, because in foo we’re not grouping the function together with anything but itself.

Named function expression: var D = function foo(){};

Here we have our same old friend, the function expression. But instead of assigning the variable to an anonymous function, we’re assigning it to a named function (with the name foo).

1. The function name is only accessible within the function

We haven’t exposed the function name (foo) to the enclosing scope (in this case the global scope):

var D = function foo(){
  console.log(typeof foo);
};
D();                       // function
console.log(typeof foo);   // undefined

2. Useful for recursion

Because the function’s name is accessible in the function itself, this turns out to be useful for recursive functions, much more useful than the plain old anonymous function.

Here’s a trivial recursive function to illustrate calling itself from within the named function expression:

var countdown = function a(count){
  if(count > 0) {
    count--;
    return a(count);  // we can also do this: a(--count), which is less clear
  }
  console.log('end of recursive function');
}
countdown(5);

3. Useful for debugging

As a few have pointed out, giving previously anonymous functions names helps in debugging, since the function name shows up on the call stack.

4. Quirks: JScript’s bad implementation

kangax points out that named function expressions are basically poison to JScript, Internet Explorer’s implementation of JavaScript.

The named function becomes a global variable, is hoisted like a function declaration, and actually ends up creating multiple instances of the same function.

Immediately-invoked function expressions (IIFE): var E = (function(){return function(){}})();

“Execute this function, whose return value is another function, and assign that to the variable E”. This may seem like magic, but it’s actually quite simple, and the pattern is powerful and has useful applications, the most famous of which is the module pattern.

First we’ll use an example that doesn’t look like magic:

var foo = function(){
  return 'bar';
};
var output = foo();
console.log(output);  // 'bar'

We already learned about grouping operators above, so you should feel comfortable with saying this is equivalent:

var foo = function(){
  return 'bar';
};
var output = (foo)(); // note the extra grouping operators
console.log(output);  // 'bar'

Since foo is pointing to our function expression, we know that we can simply refrain from using the variable “foo” and drop in the entire function as an anonymous function (since functions are first class, after all!):

var output = (function(){
  return 'bar';
})();
console.log(output);  // 'bar'

Hey wait, we just arrived at the magical resulting function! It turns out to be not so magical after all, once we break it down and see it for what it is. It’s simply shorthand for the code we wrote originally, where we defined a function, executed it, and defined output to be its return value.

I’ve included this method on the list of declaring functions because we can assign the return value to itself be a function:

var E = (function(){
  return function(){}
})();

Applications

There are good applications for this, including information hiding using in the module pattern, (partial application, for example), and other clever uses of it. It’s definitely not a trivial pattern.

Function constructor: var F = new Function();

This method is extremely old and it’s not recommended to be used. You pass in an unlimited number of arguments in the front, then the actual function body appears as a string in the last argument (because it’s a string, it’s effectively the equivalent of eval(), and isn’t recommended).

1. Defining the function

You can create a function like this:

var F = new Function('arg1', 'arg2', 'console.log(arg1 + ", " + arg2)');
F('foo', 'bar');  // 'foo, bar'

2. You don’t need the new operator

You can simply write var F = Function(); to get the same result.

3. Quirks

The MDN docs have some good examples of the quirks, including the fact that functions declared with the Function constructor don’t inherit their current scope properly (i.e. a closure isn’t formed).

What this means is that they don’t have access to variables in their enclosing scope, which isn’t particularly useful:

function foo(){
  var bar = 'blah';

  var first = new Function('console.log(typeof bar)');
  first();   // undefined

  var second = function(){
    console.log(typeof bar);
  }
  second();  // string
}
foo();

In the function “first”, we’re using the Function constructor, so it doesn’t have access to the variable bar. However, if we use the function “second”, which is a function expression, it does in fact have access to variables defined in its enclosing scope (via closure).

In other words, don’t use the Function constructor.

Special case – object constructor: var G = new function foo(){};

I saved this for last because we’re not really defining a function, though we are using the function keyword, so it’s worth noting at least.

new function(){}; creates a new object and invokes the anonymous function as its constructor. If an object is returned from the function, that becomes the resulting object, otherwise a new object is created from scratch and function is executed in the context of that new function (let’s save the details for another post!).

It’s a bit unusual to see it in this form. Let’s do it the proper way:

var Person = function(){
  console.log(this);  // Person
}
var joe = new Person();

So really with the new operator, we are giving it a new ‘this’ context and then executing the given function with that new context. Much different than the function definitions we’ve been dealing with above! This does into a whole new topic, and we’ll save that for later!

Further reading

Named function expressions demystified (kangax)

Immediately-Invoked Function Expression (IIFE) (Ben Alman)

Functions and function scope (Mozilla Developer Network – MDN)

How does an anonymous function in JavaScript work? (StackOverflow)

Function Declarations vs. Function Expressions (JavaScript, JavaScript by Angus Croll)

JavaScript: The Definitive Guide (classic book by David Flanagan)

Checking for undefined, null, and empty variables in JavaScript

Friday, February 11th, 2011

In general it’s a good practice to check for the existence of something before blindly using it by faith and hoping it works. There are various times during the execution of scripts when a variable may not be defined, it may be null, or it might be an empty string. These are three things that are easily conflated. A good way to look at this is thinking of these as having increasing levels of existence (getting a bit philosophical here for a moment…):

foo0;             // existence level 0 (creates the error "not defined")
var foo1;         // existence level 1 ("undefined" - variable declared but not defined/initialized)
var foo2 = null;  // existence level 2 (variable initialized, but isn't an Object, Number, String, etc)
var foo3 = "";    // existence level 3 (variable initialized to an empty String)
var foo4 = "bar"; // existence level 4 (variable initialized to String "foo")

Generally it would be handy if we had some way to filter out everything but the very last line. We simply want to check for these cases without the script entirely blowing up, as it does with the first line:

foo;  // ReferenceError: foo is not defined

We’re not particularly doing anything useful with foo here, but notice that the script fails out anyway. At this point any code that follows will not be executed. Your first instinct might be “Oh! I know how to contain these errors! We’ll use a try-catch!”:

try {
  foo;
} catch(e) {
  e.message;  // "foo is not defined"
}

The script still fails, but not critically, so your script continues to execute. But this turns out to aversely affect performance. The basic lesson here is that try-catch can be useful in some situations, but shouldn’t be used where alternatives are available.

typeof foo

JavaScript has quite a useful remedy for this:

typeof foo; // "undefined"

Unlike everything else in JavaScript, typeof will deal with whatever you throw at it, including undefined variables. So you can use it as a simple check before using a variable that might not exist:

if(typeof foo !== "undefined") {
  // do something with foo
}

Note that this is easy to confuse with the undefined keyword, which in this case doesn’t help us one bit, as it gives us a fatal error:

if(foo !== undefined) {  // ReferenceError: foo is not defined

}

This filters out our first two cases, since they both evaluate to “undefined”:

typeof foo; // "undefined"

var bar;
typeof bar; // "undefined"

But this turns out not to work well for our other conditions, which evaluate differently:

typeof null;  // "object" (what?!)
typeof "";    // "string"

So we need to add other “if” conditions to check.. but there turns out to be a better way!

Exploiting loose typing

JavaScript is a loosely typed language, which means that it will “automagically” cast variables into other types when necessary (i.e. when adding a Number to a String), sometimes resulting in the unexpected. For instance, whenever we use the “if” statement, the expected input is a Boolean true/false value. If JavaScript gets anything other than a Boolean, such as a String or a Number, instead of blowing up completely (as in strictly typed languages such as C), it’ll cast the variable into a Boolean for you.

“How handy!” you might think. Except in the following unexpected cases:

if("0") {
  // this will run because "0" is true
}

if("false") {
  // this will run because "false" is true
}

To see what JavaScript will cast a value to without having to use an if statement, we could create a new Boolean value with the following:

Boolean(0);    // false
Boolean("0");  // true

Or we can use the less intuitive but quick way of using double exclamation marks (this will probably award you cleverness points in someone’s book.. hopefully those points actually matter):

!!0;    // false
!!"0";  // true

This works because !foo converts foo to a Boolean but negates its original value, turning it on its head. !!foo converts foo to a Boolean and flips it back to its expected value, which is the same value that’s evaluated by our if statement.

Using this ALMOST gives us the answer we’re looking for:

!!foo0; // ReferenceError: foo0 is not defined

var foo1;
!!foo1; // false

var foo2 = null;
!!foo2; // false (same as !!null)

var foo3 = "";
!!foo3; // false (same as !!"")

var foo4 = "bar";
!!foot4; // true (same as !!"bar")

Excluding the first example, now we can test for uninitialized variables (foo1), null variables (foo2), and empty strings (foo3) all with just an if statement:

if(foo1) {
  // do something with foo1
}

if(foo2) {
  // do something with foo2
}

if(foo3) {
  // do something with foo3
}

Dang… so close! But we can’t yet test the first case without an error:

if(foo0) {  // ReferenceError: foo0 is not defined

}

foo versus window.foo and this.foo

The secret to our solution lies in how JavaScript handles undefined variables versus undefined properties. Here’s a quick reminder on the difference between the two:

// variable foo
var foo;

// property bar (and object variable foo)
var foo = {};  // create an empty object to add bar too
foo.bar = "";

The difference between these makes all the difference whether a fatal error occurs:

foo;  // ReferenceError: foo is not defined

var foo = {};
foo.bar;  // undefined
foo.blah; // undefined

We can randomly invent and check any property of foo we want, and the code will keep chugging along:

var foo = {};
foo.something = "hello";

if(foo.bar) { // undefined, interpreted as false (same as !!foo.bar)
  // never runs
}

if(foo.something) {
  foo.something;  // "hello"
}

Now comes the magic. If you know anything about JavaScript running in the browser, you know that all global variables are part of the window object. This means foo and window.foo are equivalent:

var foo;

foo === window.foo;  // true

// "this" is another bag of worms, but note this anyway
this.foo === window.foo;

So technically our variable foo is a property of the window object. So we should be able to check for any arbitrary variable in the window scope now!

window.foo;  // undefined (not a fatal error!)

// even though we're checking for the same thing, we get a fatal error…
foo;  // ReferenceError: foo is not defined

Practical uses

Now as long as we have a global entry point for our code, we can write our code in such a way that it won’t ever give us a fatal error if our variables aren’t yet defined:

if(window.foo && foo.bar) {
  foo.bar();
}

Of course nothing happens, because we haven’t defined foo. But why doesn’t foo.bar give us a fatal error? Because the first test, window.foo failed out. It would be useless processing for the JavaScript engine to also evaluate the second statement, because the end result will still be the same (false && true results in false, false && false results in false). So it doesn’t get so far as foo.bar.

And now the code will work properly when we hook up our code to our foo global namespace:

var foo = {
  bar: function() {
    alert("hello world");
  }
}

if(window.foo && foo.bar) {
  foo.bar();  // "hello world"
}

Shorthand

It’s becoming common to see an abbreviation for the above code. Check out the following two methods, which accomplish the same thing:

// Method 1
if(window.foo && foo.bar) {
  foo.bar();  // "hello world"
}

// Method 2
window.foo && foo.bar && (foo.bar());

Don’t get too scared.. these blocks of code are equivalent. Method 2 is shorter, but it simply goes something like this: if window.foo isn’t set, stop evaluating this line (just as above in the if statement). Otherwise, if foo.bar exists then execute the code in parentheses, which gives us an alert (“hello world”);

Just a word of caution about using Method 2: it’s obviously less clear what’s going on here. Your own cleverness might actually result in unnecessary confusion, especially of other people work in the same code base and they’re at different levels of understanding. In these cases we should first strive to be clear, and then only clever if it’s not at the expense of being clear.

It’s also likely that a code minifier would take care of this cleverness for us at build time, giving us the best of both worlds.

JavaScript news resources

Friday, January 14th, 2011

There’s an overwhelming amount of information being pumped out of the JavaScript community each week, but how do you keep up with it? Here’s some sources to keep you busy.

Twitter

This merits a category of its own. This has replaced the RSS reader for a lot of folks, or at the very least supplemented it.

I’ve consistently recommended Nathan Smith’s list of JavaScript folks. When I’m diligent, I keep up with this several times a week and favorite items from the feed to be considered for inclusion in that week’s JSMag Blog update.

Aggregators and communities

Delicious
Github
Reddit: web_design and javascript
JSMentors

Blogs

JavaScript Google Reader bundle
JavaScript People Blogs – Google Reader bundle

Mozilla articles on hacks.mozilla.org
Script Junkie
DailyJS – very frequently updated news by Alex Young
QuirksBlog (ppk) – focus on mobile
JavaScript, JavaScript (Angus Croll)
John Resig’s blog – unfortunately not too active lately (check out his Twitter for more updated info)
Ajaxian – used to be THE source for news, but it isn’t updated too much anymore

…and many more. Check out Rey Bango’s “What to Read to Get Up to Speed in JavaScript” for more.

Browser blogs

It’s important to know what’s going down in the browser world. These have mixed content, so it’s not just JavaScript.

Surfin’ Safari
The Chromium Blog
The Mozilla Blog

Weekly news

These sources attempt to do the legwork for you and round up the most important articles each week. (Disclaimer: I currently write for JSMag!)

JavaScript Weekly: a weekly email newsletter
Badass JS
JSMag blog

Podcasts and Videos

A Minute With Brendan
node.minutewith
YUI Theatre
Node Up

Am I missing anything (I’m very sure)? Post a link below in the comments. Thanks!

What happens when you have no JavaScript fallback?

Wednesday, January 12th, 2011

Here’s an example of what happens when your interface completely relies on JavaScript. There’s code with translated mojibake of some sort which caused the JavaScript to break. The code wasn’t in a try-catch block, so it caused all of the code on the page to fail, thus presenting me with the only part of the screen that wasn’t generated by JavaScript: the completely useless header.

Where’s the tweets!?

How to spot outdated JavaScript

Friday, January 7th, 2011

Introduction

Those that are just setting out to learn JavaScript are typically overwhelmed by the amount of online resources to be found about learning JavaScript. Not only this, but every webpage visited presents a potential learning opportunity just by inspecting the source.

However, not all resources are guaranteed to be up-to-date. JavaScript has been around for over a decade, and coding standards have changed drastically over time. While a code snippet may still work in today’s browsers, you may unknowingly be using an outdated practice that might eventually lead to a bit of embarrassment.

You may sometimes find these old practices mixed in with good and modern code. It seems that folks might learn new code styles without necessarily casting away all their old habits. So keep in mind not to throw out the baby with the bathwater!

Here’s some old practices that should help you spot old outdated code.

Global variables

function foo() {  // global function
  greeting = 'Hello' + name;  // global function
};
name = 'James';  // global variable
foo();

Tons of global variables is a sure sign of outdated code. Ideally you want to aim to have at most one global variable, which is a namespace for all your code to be written under. All variables in your functions should be defined with the ‘var’ keyword to ensure they don’t break out of their scope.

Here’s an example where we defined one global variable entry point (myNamespace) for our code:

var myNamespace = (function() {
  // declare all variables with var
  var greeting, name;

  name = 'James';

  greeting = function() {
    return 'Hello ' + name;
  };

  return {
    greeting: greeting
  }
})();

greeting();              // ERROR: not defined
myNameSpace.greeting();  // 'Hello James'

Commented CDATA blocks

/* <![CDATA[ */
// code here
/* ]]> */

This appears in old scripts that are presented inline (instead of externally in a separate file). The original purpose of those was to get around HTML validator errors (and to conform to XHTML), but that appears to no longer be an issue with validators today. Also, the usage of HTML validators itself seems to be waning, although they may sometimes be helpful in the development of websites.

document.write()

document.write('foo');

The W3C, along with most everyone else, warns against using this, as it may result in overwriting (blanking) the entire page and other unwanted behavior.

It’s now used mostly by ads, and developers have for years been trying to control them. So don’t use it, unless you’re trying to prevent ads from using them. In other words, don’t use it unless you know what you’re doing.

Inlined event handlers

<a onclick="myClickFunction()" href="http://foo.com"></a>
<a onmouseover="myMouseoverFunction()" href="http://foo.com"></a>
<form onsubmit="mySubmitFunction()" href="http://foo.com"></form>

This mixes behavior with the actual content, which means when it’s time to make changes to the code, you likely have to change both the HTML and the JavaScript, instead of simply just the JavaScript. It also means that you may be serving useless content to users with JavaScript disabled (they’re still out there, believe it or not). This also might have an affect on search engines, that might not be able to access this JavaScript-only content (although crawlers are getting more sophisticated and this may be less of an issue as time progresses).

Instead, the very least you can do is add IDs to each element (or better, use a JavaScript selector engine) and hook into them in your JavaScript, which makes the code much easier to maintain:

<a id="link1" href="http://foo.com"></a>
<a id="link2" href="http://foo.com"></a>
<form id="myForm" href="http://foo.com"></form>
(function() {  // sandbox everything
  // variable declarations
  var link1, link2, myForm;

  window.onload = function() {  // or onDOMContentLoaded (wait for DOM to be ready)
    // simple DOM selectors
    link1 = document.getElementById('link1');
    link2 = document.getElementById('link2');
    myForm = document.getElementById('myForm');

    // well-supported older event handler
    link1.onclick = function(){
      // code
    };

    // better (DOM2)
    link1.addEventListener('click', function(){ // or attachEvent for IE
      // code
    },false);

    // etc...
  }

})();

link1.onclick is widely supported, but there’s a few downsides, including the fact you can only add ONE event listener on the element (it will be overwritten if you try to add another). Use addEventListener (attachEvent in IE) instead, or the method of your favorite JavaScript engine.

In any case, the point here is to get the JavaScript out of the HTML and into the rest of your JavaScript.

Inline JavaScript in link hrefs

<a href="javascript:doSomething()"></a>
<a href="javascript:void(0)"></a>

Both of these examples commit the same error as above – mixing JavaScript behavior with the HTML content. And the solution is similar: find these links with JavaScript (most simply by adding an id on them) and hook into them there.

The second example brings up a good issue, and a point of contention. Ideally this would be a link to fallback content for users that have JavaScript disabled (and for search engines!), which would be a link to a new page (Flickr is an example of a modern site that uses this approach). For better or worse, however, you might be building a web app that only works with JavaScript, and you might want a link that only exists to kick off a JavaScript event.

You’ll find that removing the href value or making it blank (href=”") might remove the styling from the link and no longer makes it clickable. An easy fix is to set the href equal to a hash tag (href=”#”). A side effect might be a “jump” to the top of the page after clicking the link, which requires and requires e.preventDefault() within the attached event. Href=”#” may soon become an antipattern (or maybe it is already), since you can also fix this with CSS styling:

a { cursor: pointer; }

This gives the cursor a pointer when the user hovers over the link, even if it’s missing the href value.

But again, this isn’t generally recommended. It’s better to make a non-JavaScript fallback by linking to an actual page, then overriding it with e.preventDefault() for JavaScript-enabled users!

Slow arrays

var arr = [1, 2, 3, 4, 5];

for(var x in arr) {
  /* code */
}

for(var i=0; i < arr.length; i++) {
  /* code */
}

For-in loops turn out to be quite slow while going through arrays, so only use them when iterating through properties of an object. The second for loop is much faster, but can be made faster still when we realize what's being evaluated on each iteration:

for(1; n; n) {}

The first statement is evaluated once (1 time) as the loop is initialized, and the second and third parts are evaluated on each run through the loop (n times). Because of this, just as removing fluff from the main body of the loop itself, we would also do well to remove fluff from these statements themselves. As it turns out, it's quite slow finding the length of the array (arr.length) on each pass, and it's not necessary to do it more than once since it's not changing. So we can "cache" the length in a variable in the initializer:

for(var i=0, len=arr.length; i < len; i++) {
  // code
}

And faster yet is a while loop (keep in mind that it will run backwards), which stops when the counter hits 0, which is falsy, causing the loop to stop:

var i = arr.length;
while(i--) {
  // code
}

new Object(), new Array(), new Function(), etc

var obj  = new Object();
var arr  = new Array();
var func = new Function("param1", "param2", "return true;");

While these work, no one really uses them, as there exist less verbose and more common alternatives. Use these instead, which are exactly equal to the above code:

var obj  = {};
var arr  = [];
var func = function(param1, param1) {return true;}

alert()

Ok, alert can sometimes still be useful for debugging, but generally you want to use console.log for that anyway. Generally you don't want to ever prompt the user with alert() however. Its use on the desktop for mainstream use has long been discouraged.

I'm still on the fence about using alert() however, as I think it's pretty useful and not necessarily ugly in mobile browsers. I'll spare you and save that for another post.

Missing semicolons

var name='Bill'
alert('Hi ' + name)

The above code works fine because of a controversial feature of JavaScript called semicolon insertion. But doesn't it make you feel dirty? It should, especially if you've read JavaScript: The Good Parts. Use semicolons for your own good and to prevent major headaches. Leave it to your JavaScript minifier to be clever in deciding when to remove them:

var name='Bill';
alert('Hi ' + name);

Code for particular user agents

This is also a bit controversial, since unfortunately user agent sniffing is still sometimes necessary. However, in the past it was really abused with code such as this:

isIE  = document.all;
isNS4 = document.layers;
isNS6 = document.getElementById;
if(isIE) {
  // code for IE
} else if(isNS4) {
  // code for Netscape 4
} else if(isNS6) {
  // code for Netscape 6
}

(did I mention that any references to ancient browsers like Netscape is also a surefire sign of old code? But that's probably too obvious...)

This example detects browsers by features that only exist in each of these old browsers, but the same sin is committed by "sniffing" for words in the user agent string. The unfortunate result is fragmented code targeting each predetermined browser. Not to mention that it's not future-proof, as it can't properly anticipate newer browsers.

The better method? If there's a question about the availability of a method, simply check for it first before using it:

if(document.addEventListener) {  // detect addEventListener
  // Try the standard first
  document.addEventListener('click', function(){}, false);
} else if(document.attachEvent) {  // detect attachEvent
  // Typically IE
  document.attachEvent('onclick', function(){});
}

This code is considered feature detection, which is much more acceptable. It also anticipates newer browsers such as IE9, which support addEventListener. This makes sure the code you write doesn't condemn Internet Explorer to forever use attachEvent.

Related links

Christian Heilmann and PPK's old posts inspired me to write this brief post. You can read much better rationale against using some of the things above at these links:

Six JavaScript features we do not need any longer (Christian Heilmann, 2005)

From DHTML to DOM scripting (Christian Heilmann, 2006)

Three JavaScript articles and one best practice (PPK 2005)