

Ask HN: Javascript best practices? - mattiss

How much does it make sense to decompose your javascript routines into separate files? Do you have .js for related classes and methods and one page wide .js to call everything else?<p>EDIT: The above was just an example, I'm looking for most things related to JS.
======
n8agrin
Always use "var" to define a variable, unless you know exactly what you are
doing. e.g.:

    
    
      var foo = 'bar';
    

When you don't use "var" the Javascript interpreter breaks out of the current
scope and continues to do so all the way until it hits the final global scope
(generally the window object in browsers). If it does not find the variable,
it then defines it. If it does find it, it will trample the found variable
with the new value. For example:

    
    
      var foo = 'bar';
    
      function baz() {
        foo = 'baz';
      }
    
      baz();
    
      // now foo == 'baz';
      console.log(foo);
      >>'baz'
    

Google "Javascript var keyword" for more info.

EDIT: I'll add that this functionality, which is part of a general language
feature known as a "closure", is incredibly powerful when used successfully,
but that's out of the scope of my comment.

~~~
tyrmored
Also, "scope" means inside a function, and not inside a control block (e.g.
for loops).

I would estimate global variables will cause at least 50% of the headaches an
intermediate JavaScript developer experiences. It's particularly bad when
you're dealing with rows of data, for example.

Get in the habit of declaring every variable in the top line of the function
concerned before you use it. If you haven't already mastered closures, this
will make things a lot easier for you.

------
mindviews
I like to use separate files for organization during development and then
merge and minify for deployment. Just make sure you have an automated process
because you don't want to make mistakes doing it by hand.

~~~
alexitosrv
Any tool suggestions for the job of minifying and deployment?

~~~
gz
<http://developer.yahoo.com/yui/compressor/>

~~~
mlLK
+1 for YUI

+2 Grok Douglas Crockford's DOM theory then optimize how your scripts use the
DOM, it is very easy to abuse the DOM, don't. Grok the DOM.

------
thingsilearned
Many frameworks have some tools for dealing with multiple javascript files. I
use django-compress for example and love it.

It allows you to have many different javascript files to separate your code
logically, and it automatically compresses them into one file for you for
deployment. In this way you don't have to compromise speed for clarity.

If you're interested in advanced JS I highly recommend this book.
<http://jspro.org/>

~~~
wenbert
I have been eyeing books for months now. Pro Javascript Techniques has been
one of them. Living in a country where shipping costs as much as a book is
hard.

~~~
mechanical_fish
_Living in a country where shipping costs as much as a book is hard._

Might Safari Books Online work for you?

<http://www.safaribooksonline.com/>

I prefer the physical book to reading from a browser, but if the price is
right...

------
rudenoise
I like Douglas Crockford's opinions and advice on many aspects of JavaScript:

<http://javascript.crockford.com/>

Conventions:

<http://javascript.crockford.com/code.html>

and his book "JavaScript The Good Parts" is well worth a read, even to
experiences JS developers

[http://www.amazon.com/exec/obidos/ASIN/0596517742/wrrrldwide...](http://www.amazon.com/exec/obidos/ASIN/0596517742/wrrrldwideweb)

------
irrelative
Just my 2 cents: Javascript gives you plenty of rope to hang yourself with.
Personally, I try to stay away from prototypical objects unless the style fits
very cleanly with what I'm trying to do. Otherwise,the best way I've found to
keep my sanity is to pick whatever language you're developing the backend
with, and use as many conventions you've established there as possible.

For me, this means my Javascript looks more like Python -- it can be a little
weird, but switching between the frontend and the backend is easier that way.

I'd also recommend using objects as namespaces if you're not dealing with
prototypical objects. It makes grepping easier - you can search for
'Graphs.init' instead of 'init' in this example:

var Graphs = {

    
    
        state_variable: null, // store global state somehow
    
        init: function() {
            // Some initialization code
        },
    
        refresh: function(img_element, url) {
            // some code to refresh the src url
        }

};

------
taitems
Just remember that sometimes doing things the "right" way can really slow your
code down. I started coding believing that text should be added with
createTextNode and any HTML element should be created via createElement.

This causes two issues:

1\. Memory leaks from deleted or hidden DOM that is still referenced.

2\. Performance. innerHTML is still probably the fastest method of adding
elements, as dirty as it seems.

------
kls
I tend to create a page controller js file that my html file loads. I do not
embed any JavaScript in the page rather, I grab any dom elements that I need
via JavaScript so that way there is a clean separation between code and HTML.
I tend to prefer Dojo as far as frameworks, so i will use dojo.byId or
dijit.byId to grab references to my nodes in my page init function.

I intentionally make my controller file procedural and then I have a custom
life-cycle event controller that fires off events for page init, reload, load
data, page unload, etc.. so my developers can just fill in the blanks. Any
data access is done by calling methods on a service facade which again is
purposefully procedural. The service facade then calls any server side
services we need (we don't do form posts any more, JSON is far more robust for
submitting data). Finally, we use Dijit for any of our widget and any of our
model / utility / OO needs.

I know it's no purely JavaScript best practices, and it is more related to
project file layout and architecture, but I find it gives me the best
architecture for my team size (100+). It helps me on-board people quickly and
graduate their skill set while maintaining clean code and allowing advanced
features.

I can start a junior on pure html layout, then we can train them to do
controller modification, then to work on service facades and then when they
have a good foundation in prototype base OO we can graduate them into building
reusable widgets and subsystems for the controller and service facade
developers. It works well and allows developers to work proficiently at their
skill set without mucking up the whole system.

As well the service facades make it easy to contract out entire web projects
while my internal team builds server side services to support the effort. This
allows us to expand our work force, to a larger pool, without having to vet
new developers to deep into business rules to get them up and running.

------
csytan
I'll assume this is for client side js, since that's what most people use =)

Most of the js I write involves jQuery. As such, I find it's very useful to
separate reusable components into jQuery plugins in separate files. If you
don't use jQuery or another library which allows plugins, then it's best to
create your own namespaced module.

See the "Module pattern" for more info:
<http://www.yuiblog.com/blog/2007/06/12/module-pattern/>

Depending on the complexity of your code, you might want to look into
javascript build systems -- there's at least one for every major web
framework.

Here's some advantages they offer: \- Allow bunding of many js files into one
mega js file. (reduces HTTP requests for faster page loading) \- Specify
javascript dependencies using special syntax. (easier maintenance) \-
Versioning support (so users don't get an old cached version of your code)

When bundling js files, I try to aim for a maximum of two js files per page.
One contains code which is global to the whole site (this is cached on
subsequent views), and the second which contains page specific code.

------
gtani
Big topic, here's things i refer to repeatedly

<http://yuiblog.com/blog/2008/09/26/oojs/>

<http://yuiblog.com/assets/pdf/oojs-ch-8.pdf>

[http://mashraqi.com/2008/07/high-performance-ajax-
applicatio...](http://mashraqi.com/2008/07/high-performance-ajax-
applications.html)

[http://www.smashingmagazine.com/2008/09/16/jquery-
examples-a...](http://www.smashingmagazine.com/2008/09/16/jquery-examples-and-
best-practices/)

[http://dev.opera.com/articles/view/the-seven-rules-of-
unobtr...](http://dev.opera.com/articles/view/the-seven-rules-of-unobtrusive-
javascrip/)

[http://www.reddit.com/r/programming/comments/7rtxa/has_anyon...](http://www.reddit.com/r/programming/comments/7rtxa/has_anyone_else_hated_javascript_but_later/)

<http://code.google.com/p/jslibs/wiki/JavascriptTips>

------
dan_sim
3 years ago, I started a blog about javascript called Javascript Kata at
<http://www.javascriptkata.com> . I will try to write more and more about best
practices and new ways of doing things.

------
whalesalad
Can anyone elaborate on when one giant JS file (benefit here is of course
reducing HTTP requests) becomes too large? Right now I am splitting up JS
files in a fairly simple manner: a single site-wide file with common methods
and utilities, and then a handful of smaller files for various aspects of the
site. I think that they are each small enough to all be combined into one
single one... but when is that single file too large?

~~~
dasil003
Most of the time never. Additional files means additional connection overhead.
Browsers typically won't open more than 2 simultaneous connections to the same
host, so too many assets can quickly lead to noticeable delays.

The one exception I can think of is if you have a lot of JS code, but some of
it needs to load faster. In that case you may want to split the code into
several files based on load priority. If you go that route you may want to
also use multiple asset subdomains or ideally a CDN to minimize latency.

------
seanlinmt
I found this quite good for constructing tidy javascript code,
<http://ejohn.org/apps/learn/>

I haven't had time to look into this but there's also a project called Doloto
to help optimise your javascript, <http://research.microsoft.com/en-
us/projects/doloto/>

------
geuis
Use ===, !== etc instead of == or !=. They aren't the same

------
erlanger
* Comment with JSDoc style

* Auto-build docs and script for development and production environemnts (easy to concatenate and then pipe this to YUI Compressor)

* Use an MVC project organization or something like-minded. You can't just throw files representing widgets around.

* Write unit tests. JSUnit and SrewUnit (I prefer the latter) work well for this.

* Format your code nicely (this goes for any code but I find a ton of terribly formatted JS)

* Use one common library for any core object prototype changes (on Element, Array, Function, etc.) and don't modify them further.

* JSLint code you're unsure about.

* The best way to dynamically load code is just to write script tags to the document.

A few style-concerned ones...

* Don't use the module pattern. It's rarely appropriate, hiding methods does nobody good, just use a closure.

* Only create elements when absolutely necessary and destroy ones that you will no longer use. There's no garbage collector in that regard.

* Use a routing system to manipulate and read document.location.hash (and the browser history) so that pages have real URLs and navigate like webpages.

* Callbacks and delegates are great, they should be used all over the place.

* Use events and listeners to connect the parts of your app.

~~~
entelarust
Great points

Just curious. For large scale projects, do you suggest building on top of
existing javascript libraries (i.e. prototype, jQuery, mootools, etc)?

~~~
mattiss
+1 for jQ

------
ilyak
When I hear "best practices" I reach for my Giant Spiked Club of Holy Wrath.

~~~
dmnd
Why? What's so terrible about finding out about how those more experienced
than yourself do things? I'm assuming, of course, that sound reasoning is
supporting the practice rather than simple cargo culting.

~~~
ilyak
It's cargo culting more often than not.

For some reason, people don't follow good advices which require changing code
logic, refactoring and such: they follow advices where you need to format
everything in the longest possible way and write a lot of boilerplate.

Because it's just easier for some people.

------
adrianwaj
Obfuscate variable and function names with junk words. On Windows, Jasob was
easily the best <http://www.jasob.com/> for it (I tried using many others
including online offerings). You need to do this if worried about others
seeing and using your code, especially competitors.

edit: am I stupid? But when you obfuscate, you also radically shorten the
length of a JS file, thus making it quicker to download: EG:

function c(g){var m=0;while(m<g.length){var
r=g[m];r.l=d(r.n,r.o);if(r.j==true){
r.k=e(r.n,r.o,r.l);}else{r.k=0;}r.t=f(r.l+r.k);m++;}}

~~~
mattiss
You are talking about minifying, which is great for bandwidth reduction and I
suppose obfuscation.

However this post was about JS design principles.

