What anti-patterns exist for JavaScript?

JavascriptAnti Patterns

Javascript Problem Overview


I find that what not to do is a harder lesson to learn than what should be done.

From my experience, what separates an expert from an intermediate is the ability to select from among various seemingly equivalent ways of doing the same thing.

So, when it comes to JavaScript what kinds of things should you not do and why?

I'm able to find lots of these for Java, but since JavaScript's typical context (in a browser) is very different from Java's I'm curious to see what comes out.

Javascript Solutions


Solution 1 - Javascript

Language:

  • Namespace polluting by creating a large footprint of variables in the global context.

  • Binding event handlers in the form 'foo.onclick = myFunc' (inextensible, should be using attachEvent/addEventListener).

  • Using eval in almost any non-JSON context

  • Almost every use of document.write (use the DOM methods like document.createElement)

  • Prototyping against the Object object (BOOM!)

  • A small one this, but doing large numbers of string concats with '+' (creating an array and joining it is much more efficient)

  • Referring to the non-existent undefined constant

Design/Deployment:

  • (Generally) not providing noscript support.

  • Not packaging your code into a single resource

  • Putting inline (i.e. body) scripts near the top of the body (they block loading)

Ajax specific:

  • not indicating the start, end, or error of a request to the user

  • polling

  • passing and parsing XML instead of JSON or HTML (where appropriate)

Many of these were sourced from the book Learning JavaScript Design by Addy Osmati: https://www.oreilly.com/library/view/learning-javascript-design/9781449334840/ch06.html

edit: I keep thinking of more!

Solution 2 - Javascript

Besides those already mentioned...

  • Using the for..in construct to iterate over arrays
    (iterates over array methods AND indices)

  • Using Javascript inline like <body onload="doThis();">
    (inflexible and prevents multiple event listeners)

  • Using the 'Function()' constructor
    (bad for the same reasons eval() is bad)

  • Passing strings instead of functions to setTimeout or setInterval
    (also uses eval() internally)

  • Relying on implicit statements by not using semicolons
    (bad habit to pick up, and can lead to unexpected behavior)

  • Using /* .. */ to block out lines of code
    (can interfere with regex literals, e.g.: /* /.*/ */)

    <evangelism> And of course, not using Prototype ;) </evangelism>

Solution 3 - Javascript

The biggest for me is not understanding the JavaScript programming language itself.

  • Overusing object hierarchies and building very deep inheritance chains. Shallow hierarchies work fine in most cases in JS.
  • Not understanding prototype based object orientation, and instead building huge amounts of scaffolding to make JS behave like traditional OO languages.
  • Unnecessarily using OO paradigms when procedural / functional programming could be more concise and efficient.

Then there are those for the browser runtime:

  • Not using good established event patterns like event delegation or the observer pattern (pub/sub) to optimize event handling.
  • Making frequent DOM updates (like .appendChild in a loop), when the DOM nodes can be in memory and appended in one go. (HUGE performance benefit).
  • Overusing libraries for selecting nodes with complex selectors when native methods can be used (getElementById, getElementByTagName, etc.). This is becoming lesser of an issue these days, but it's worth mentioning.
  • Extending DOM objects when you expect third-party scripts to be on the same page as yours (you will end up clobbering each other's code).

And finally the deployment issues.

  • Not minifying your files.
  • Web-server configs - not gzipping your files, not caching them sensibly.

<plug> I've got some client-side optimization tips which cover some of the things I've mentioned above, and more, on my blog.</plug>

Solution 4 - Javascript

  • browser detection (instead of testing whether the specific methods/fields you want to use exist)
  • using alert() in most cases

see also Crockford's "Javascript: The Good Parts" for various other things to avoid. (edit: warning, he's a bit strict in some of his suggestions like the use of "===" over "==" so take them with whatever grain of salt works for you)

Solution 5 - Javascript

A few things right on top of my head. I'll edit this list when I think of more.

  • Don't pollute global namespace. Organize things in objects instead;
  • Don't omit 'var' for variables. That pollutes global namespace and might get you in trouble with other such scripts.

Solution 6 - Javascript

any use of 'with'

> > with (document.forms["mainForm"].elements) {
> input1.value = "junk";
> input2.value = "junk"; > }

Solution 7 - Javascript

any reference to

document.all

in your code, unless it is within special code, just for IE to overcome an IE bug. (cough document.getElementById() cough)

Solution 8 - Javascript

Bad use of brace positioning when creating statements

You should always put a brace after the statement due to automatic semicolon insertion.

For example this:

function()
{
    return
    {
        price: 10
    }
}

differs greatly from this:

function(){
    return{
        price: 10
    }
}

Becuase in the first example, javascript will insert a semicolon for you actually leaving you with this:

function()
{
    return;    // oh dear!
    {
        price: 10
    }
}

Using setInterval for potentially long running tasks.

You should use setTimeout rather than setInterval for occasions where you need to do something repeatedly.

If you use setInterval, but the function that is executed in the timer is not finished by the time the timer next ticks, this is bad. Instead use the following pattern using setTimeout

function doThisManyTimes(){
    alert("It's happening again!");
}

(function repeat(){
    doThisManyTimes();
    setTimeout(repeat, 500);
})();

This is explained very well by Paul Irish on his 10 things I learned from the jQuery source video

Solution 9 - Javascript

Not using a community based framework to do repetitive tasks like DOM manipulation, event handling, etc.

Solution 10 - Javascript

Effective caching is seldomly done:

  • Don't store a copy of the library (jQuery, Prototype, Dojo) on your server when you can use a shared API like Google's Libraries API to speed up page loads
  • Combine and minify all your script that you can into one
  • Use mod_expires to give all your scripts infinite cache lifetime (never redownload)
  • Version your javascript filenames so that a new update will be taken by clients without need to reload/restart (i.e. myFile_r231.js, or myFile.js?r=231)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAllain LalondeView Question on Stackoverflow
Solution 1 - JavascriptannakataView Answer on Stackoverflow
Solution 2 - JavascriptKenan BanksView Answer on Stackoverflow
Solution 3 - JavascriptRakesh PaiView Answer on Stackoverflow
Solution 4 - JavascriptJason SView Answer on Stackoverflow
Solution 5 - JavascriptVilx-View Answer on Stackoverflow
Solution 6 - JavascriptGreg DeanView Answer on Stackoverflow
Solution 7 - JavascriptscunliffeView Answer on Stackoverflow
Solution 8 - JavascriptSwaffView Answer on Stackoverflow
Solution 9 - JavascriptAllain LalondeView Answer on Stackoverflow
Solution 10 - JavascriptJoseph LustView Answer on Stackoverflow