
Javascript Tips for Non-Specialists  - rbanffy
http://omniti.com/seeds/javascript-tips-for-non-specialists
======
geuis
Good tips overall.

I'd recommend a couple of changes though.

"Don’t Touch the Doc (Unless You Have To)"

This should say, "Don't Touch the DOM (Unless You Have To)". The reason is
that it's almost never referred to as the Document, and always referred to as
the DOM. If you have programmers new to js, they will find much more info when
using the correct terminology. Since we're in the spirit of education, lets
teach the right things.

I'd love to see this less in paragraph form and more in code form. Programmers
are used to skimming through code. Eyes start wandering when having to extract
programmer concepts from dense text. This is, of course, my own opinion and
totally subjective.

~~~
firefoxman1
On that same note, as a performance tip I would expand it to "Cache your
property lookups." Caching _obj.property_ in a variable is much faster if
you're going to reference it more than twice.

~~~
gillespie
Is this still true on modern browsers with optimising js engines? And if so,
why?

~~~
firefoxman1
Well, according to this answer (<http://stackoverflow.com/a/7701264>) V8 is
about the same speed as accessing variables, however I would bet looking up
properties higher up the prototype chain would take a performance hit.

~~~
gillespie
I was thinking more that if you repeatedly access a property, regardless of
where in the prototype chain it is, the optimiser would cache the value, so it
would be equivalent to saving it in a local variable. If I'm not mistaken,
this is a common feature in optimizing compilers. I don't know how aggressive
the JIT js compilers are, however.

~~~
firefoxman1
Hmm that's pretty interesting. I don't really like to depend on the engine for
optimizations because you never know what JS engine people have, but it's good
to know they do that.

------
grayrest
If you're a developer, this is what you need to know when writing javascript:

<http://bonsaiden.github.com/JavaScript-Garden/>

It's not that long and it covers all the major points of confusion.

Edit: Also, ignore point 4 of the linked article. Selector performance is an
area that used to matter but is now a non-factor.

~~~
corford
Thanks for the JG link. Just checked it out and it's exactly the kind of
modern JS resource I've been trying to find for the last few weeks.

------
scottfr
I never understood the vehemence against inline javascript. From the article,
how is this:

    
    
       <button id="my_btn" onclick="doThis();">Submit</button>
    

Supposed to be worse than:

    
    
       <button type="button" id="my_btn">Submit</button>
    

combined with (usually located in a different file or several hundred lines
away):

    
    
       document.getElementById("my_btn").addEventListener("click", doThis);
    

It seems like the latter is much more difficult to maintain. Sure inlining
much more than a simple function call get's hairy, but for a simple action
inlining always seemed much cleaner and easier to maintain to me. It's much
nicer than a whole bunch of addEventListener's or bind calls in your JS.

~~~
mechanical_fish
The article provides Argument A against inline JS: "Show me all the dynamic JS
that gets loaded for this page" is a more important case to optimize for than
"show me exactly which JS statement is tied to this button".

This is particularly true because, in your example, having onclick="doThis();"
in the HTML isn't all that helpful if you need to know exactly what doThis();
is doing. You'll _still_ have to go find the actual block of JS that's
defining doThis(), and that will still be someplace else.

Yes, it might be nice to have that short descriptive name associated with the
button, but that's what class="does-this" is for.

Other arguments against inline JS:

It's harder to test the case where JS is turned off.

It's harder to ensure that all buttons of class "play" have the "playMe()"
function attached. Doing it one button at a time is very un-DRY; you are going
to miss one during some edit or other. Similarly, if you decide that buttons
should call playMeLoudly() instead of playMe(), you have a lot more lines of
code to change.

With inline JS you are always one missing quote character away from a security
incident. As I know from having played the awesome Stripe-CTF game, <script>
tags are not your friend! They are very scary and should be very boring and
kept away from your markup and edited as little as possible, and script-tags-
in-disguise like "onclick" attributes should be regarded with suspicion.

------
jfaucett
Good article, all important things to know when starting out. Semi-related I
have a question. Does anyone do extensive js caching? I've kind of gotten into
the habbit (for highly interactive single pages that would normally have a lot
of ajax calls) of loading my page with a start chunk of my dom elements into a
hidden div. Then I ajax load the rest and clone the dom/objects saving them in
a cache. I've noticed it speeding up my apps (minimizes http request, also
clones only occur once) anyone have any thoughts here or better methods?

------
hcarvalhoalves
Good tips. Specially comparison operators.

The fact Javascript has both "null" and "undefined" is not just a stupid idea,
but might be the biggest source of stupid bugs. You need a long, repetitive
construct everytime you check a variable:

    
    
        if((typeof banana === "undefined") || (!banana)) {
            banana = "banana";
        }
    

But instead you see code like:

    
    
        if(banana == null) {
            ...
        }
    

Argh!

~~~
thezilch

      if(!window.banana) banana = "banana";

~~~
masklinn
I generally prefer:

    
    
        var banana;
        if (!banana) babana = "banana";
    

or

    
    
        var banana;
        banana = banana || "banana";
    

I have a strong dislike for implicit globals — even at the toplevel — and the
global object isn't necessarily `window` (it's not in the Spidermonkey or Node
shells for instance, I'm not sure it is in Web Workers — there's a
WorkerGlobalScope object but i don't know if it's bound to a global called
`window`).

If `undefined` has to be checked for explicitly (because `null` or `0` or `""`
are valid values), check `banana === undefined` (or `banana === void 0` if
your coworkers are assholes)

~~~
thezilch
I don't disagree; it was just the briefest example, which assumed that window
was the scope -- couldn't really think of a reason I'd warrant an inner scope
to have uninitialized vars.

So, to the OP, you can always check that your var is a member of some object,
including window. The typeof example is bad form.

------
jcampbell1
I think points 4 and 5 are just premature optimization.

$('input[name=firstname]') is better than $('#firstname') because with the
latter you don't know whether you have an input, or some div containing a
label and an input. The speed difference is meaningless.

The example in 5 doubles the amount of code and only provides a speed benefit
if you are constantly setting a value to the same thing which indicates there
is some other problem with your strategy. #5 is a code smell to me.

~~~
kamjam
_I think points 4 and 5 are just premature optimization.... The speed
difference is meaningless._

There's no such thing as premature optimization or meaningless speed
differences. Would you say the same thing if the code was in Java/C#/Ruby etc?

It may appear to make no difference on a site with hardly any JS interaction,
but throw in a few plugins, a decent amount of AJAX and more than a handful of
lines of JS and all of a sudden all those milliseconds have led to a delay of
a few of seconds while your page finishes rendering.

~~~
mattmanser
Yes, many programmers would say exactly that in those languages. Code
readability is very important.

This is a debate that flares up every year or so, but a lot of programmers
generally consider premature optimization to be a complete waste of time and
bad for your code. They would tell you to write clear code and use a profiler
to find actual bottlenecks, not spend time fixing imagined ones.

~~~
kamjam
Fair point, and I'd agree with you - I'd defo go over clearer code than
something purely for premature optimization... except I think the examples
given were MORE readable afterwards, at worst you've ended up with optimised
code!

Problem with JS is that there is not as many optimization tools, aside from
Firebug that I can think of. On top of that, personally, I'm a C# guy that
does some JS and most people I know are like me. The other guys that do JS
work for design agencies that are more front-end/HTML guys. Most of us aren't
tooled up like in the C# world for optimization and rely on optimization tips
- it's a lot easier to do these as you go along rather than retrospectively
like you can with server languages. (I may well be missing a whole toolset
here somewhere - be good to find more resources)

------
theballwatcher
Expanding on the first tip, this is a pretty good piece on scope and execution
context in javascript - [http://davidshariff.com/blog/what-is-the-execution-
context-i...](http://davidshariff.com/blog/what-is-the-execution-context-in-
javascript/)

