Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Javascript Tips for Non-Specialists (omniti.com)
76 points by rbanffy on Aug 28, 2012 | hide | past | favorite | 31 comments


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.


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.


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


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.


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.


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.


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.


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.


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.


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.


There are major HTML platforms, like Windows 8 applications and the new Chrome apps, where inline event handlers are verboten because of the potential for allowing XSS attacks on applications from external content. Giving only JS code the ability to register more JS code removes this attack surface.


I like being able to change the behavior of my application without having to make changes in the markup (some of which can even ripple out into the stylesheets). Things just scale more cleanly as the app's complexity increases, and the separation of concerns feels much more productive than having to search through hundreds of lines of HTML for in-lined function calls.


To add to the other reasons, It's a right pain in the ass when automating browsers to test your app as you can't click an anchor (it's a security thing).

So this will cause problems, which MS used to use all the time in their frameworks:

    <a href="javascript:CantClickMeWithCode();">thing</a>
MS have even come up with a term for not doing it 'unobtrusive javascript'. It doesn't really seem to be catching on as I've not seen anyone but the ASP.Net team use it.


What if you want to load JS asynchronously? How do you know that `doThis()` is defined?


I also believe that inline js code is cleaner and easier to find.


I personally don't like javascript in my HTML, and vice versa.


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?


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!


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


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)


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.


"If there's no attribute on the window object, let's define a global"

In any other language this would mean a complete different thing. This can only be obvious in the world of Jamie Zawinski.


Why Zawinski? Do you mean Brendan Eich?


Ha! You're correct. It's because I attribute Netscape as being the culprit for Javascript being around ;)


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.


Wouldn't you be better to do

  var firstnameTextBox = $('#firstname')
Or name your IDs more appropriately?

It depends on your use case, but I don't think it's right to say any speed increase is meaningless.


Just a note: $('input[name=firstname]') and $('#firstname') are not same. First one returns an input with name firstname whereas seconds one returns and element with id firstname.


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.


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.


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)


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...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: