Menu Search
Jump to the content X X
Smashing Conf Barcelona 2016

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

Seven JavaScript Things I Wish I Knew Much Earlier In My Career

I’ve been writing JavaScript code for much longer than I care to remember. I am very excited about the language’s recent success; it’s good to be a part of that success story. I’ve written dozens of articles, book chapters and one full book on the matter, and yet I keep finding new things. Here are some of the “aha!” moments I’ve had in the past, which you can try out rather than waiting for them to come to you by chance.

Shortcut Notations Link

One of the things I love most about JavaScript now is shortcut notations to generate objects and arrays. So, in the past when we wanted to create an object, we wrote:

var car = new Object();
car.colour = 'red';
car.wheels = 4;
car.hubcaps = 'spinning';
car.age = 4;

The same can be achieved with:

var car = {
  colour:'red',
  wheels:4,
  hubcaps:'spinning',
  age:4
}

Much shorter, and you don’t need to repeat the name of the object. Right now, car is fine, but what happens when you use invalidUserInSession? The main gotcha in this notation is IE. Never ever leave a trailing comma before the closing curly brace or you’ll be in trouble.

The other handy shortcut notation is for arrays. The old school way of defining arrays was this:

var moviesThatNeedBetterWriters = new Array(
  'Transformers','Transformers2','Avatar','Indiana Jones 4'
);

The shorter version of this is:

var moviesThatNeedBetterWriters = [
  'Transformers','Transformers2','Avatar','Indiana Jones 4'
];

The other thing about arrays is that there is no such thing as an associative array. You will find a lot of code examples that define the above car example like so:

var car = new Array();
car['colour'] = 'red';
car['wheels'] = 4;
car['hubcaps'] = 'spinning';
car['age'] = 4;

This is not Sparta; this is madness—don’t bother with this. “Associative arrays” is a confusing name for objects.

Another very cool shortcut notation is the ternary notation for conditions. So, instead of the following…

var direction;
if(x < 200){
  direction = 1;
} else {
  direction = -1;
}

… You could write a shorter version using the ternary notation:

var direction = x < 200 ? 1 : -1;

The true case of the condition is after the question mark, and the other case follows the colon.

JSON As A Data Format Link

Before I discovered JSON to store data, I did all kinds of crazy things to put content in a JavaScript-ready format: arrays, strings with control characters to split, and other abominations. The creation of JSON1 by Douglas Crockford changed all that. Using JSON, you can store complex data in a format that is native to JavaScript and doesn't need any extra conversion to be used immediately.

JSON is short for "JavaScript Object Notation" and uses both of the shortcuts we covered earlier.

So, if I wanted to describe a band, for example, I could do the following:

var band = {
  "name":"The Red Hot Chili Peppers",
  "members":[
    {
      "name":"Anthony Kiedis",
      "role":"lead vocals"
    },
    {
      "name":"Michael 'Flea' Balzary",
      "role":"bass guitar, trumpet, backing vocals"
    }, 
    {
      "name":"Chad Smith",
      "role":"drums,percussion"
    },
    {
      "name":"John Frusciante",
      "role":"Lead Guitar"
    }
  ],
  "year":"2009"
}

You can use JSON directly in JavaScript and, when wrapped in a function call, even as a return format of APIs. This is called JSON-P and is supported by a lot of APIs out there. You can use a data endpoint, returning JSON-P directly in a script node:

<div id="delicious"></div><script>
function delicious(o){
  var out = '<ul>';
  for(var i=0;i<o.length;i++){
    out += '<li><a href="' + o[i].u + '">' + 
           o[i].d + '</a></li>';
  }
  out += '</ul>';
  document.getElementById('delicious').innerHTML = out;
}
</script>
<script src="http://feeds.delicious.com/v2/json/codepo8/javascript?count=15&callback=delicious"></script>

This calls the Delicious Web service to get my latest JavaScript bookmarks in JSON format and then displays them as an unordered list.

In essence, JSON is probably the most lightweight way of describing complex data—and it runs in a browser. You can even use it in PHP using the json_decode() function.

Native JavaScript Functions (Math, Array And String) Link

One thing that amazed me is how much easier my life got once I read up thoroughly on the math and string functions of JavaScript. You can use these to avoid a lot of looping and conditions. For example, when I had the task of finding the largest number in an array of numbers, I used to write a loop, like so:

var numbers = [3,342,23,22,124];
var max = 0;
for(var i=0;i<numbers.length;i++){
  if(numbers[i] > max){
    max = numbers[i];
  }
}
alert(max);

This can be achieved without a loop:

var numbers = [3,342,23,22,124];
numbers.sort(function(a,b){return b - a});
alert(numbers[0]);

Notice that you cannot use sort() on a number array because it sorts lexically. There's a good tutorial on sort() here2 in case you need to know more.

Another interesting method is Math.max(). This one returns the largest number from a list of parameters:

Math.max(12,123,3,2,433,4); // returns 433

Because this tests for numbers and returns the largest one, you can use it to test for browser support of certain properties:

var scrollTop= Math.max(
 doc.documentElement.scrollTop,
 doc.body.scrollTop
);

This works around an Internet Explorer problem. You can read out the scrollTop of the current document, but depending on the DOCTYPE of the document, one or the other property is assigned the value. When you use Math.max() you get the right number because only one of the properties returns one; the other will be undefined. You can read more about shortening JavaScript with math functions here3.

Other very powerful functions to manipulate strings are split() and join(). Probably the most powerful example of this is writing a function to attach CSS classes to elements.

The thing is, when you add a class to a DOM element, you want to add it either as the first class or to already existing classes with a space in front of it. When you remove classes, you also need to remove the spaces (which was much more important in the past when some browsers failed to apply classes with trailing spaces).

So, the original function would be something like:

function addclass(elm,newclass){
  var c = elm.className;
  elm.className = (c === '') ? newclass : c+' '+newclass;
}

You can automate this using the split() and join() methods:

function addclass(elm,newclass){
  var classes = elm.className.split(' ');
  classes.push(newclass);
  elm.className = classes.join(' ');
}

This automatically ensures that classes are space-separated and that yours gets tacked on at the end.

Event Delegation Link

Events make Web apps work. I love events, especially custom events, which make your products extensible without your needing to touch the core code. The main problem (and actually one of its strengths) is that events are removed from the HTML—you apply an event listener to a certain element and then it becomes active. Nothing in the HTML indicates that this is the case though. Take this abstraction issue (which is hard for beginners to wrap their heads around) and the fact that "browsers" such as IE6 have all kind of memory problems and too many events applied to them, and you'll see that not using too many event handlers in a document is wise.

This is where event delegation4 comes in. When an event happens on a certain element and on all the elements above it in the DOM hierarchy, you can simplify your event handling by using a single handler on a parent element, rather than using a lot of handlers.

What do I mean by that? Say you want a list of links, and you want to call a function rather than load the links. The HTML would be:

<h2>Great Web resources</h2>
<ul id="resources">
  <li><a href="http://opera.com/wsc">Opera Web Standards Curriculum</a></li>
  <li><a href="http://sitepoint.com">Sitepoint</a></li>
  <li><a href="http://alistapart.com">A List Apart</a></li>
  <li><a href="http://yuiblog.com">YUI Blog</a></li>
  <li><a href="http://blameitonthevoices.com">Blame it on the voices</a></li>
  <li><a href="http://oddlyspecific.com">Oddly specific</a></li>
</ul>

The normal way to apply event handlers here would be to loop through the links:

// Classic event handling example
(function(){
  var resources = document.getElementById('resources');
  var links = resources.getElementsByTagName('a');
  var all = links.length;
  for(var i=0;i<all;i++){
    // Attach a listener to each link
    links[i].addEventListener('click',handler,false);
  };
  function handler(e){
    var x = e.target; // Get the link that was clicked
    alert(x);
    e.preventDefault();
  };
})();

This could also be done with a single event handler:

(function(){
  var resources = document.getElementById('resources');
  resources.addEventListener('click',handler,false);
  function handler(e){
    var x = e.target; // get the link tha
    if(x.nodeName.toLowerCase() === 'a'){
      alert('Event delegation:' + x);
      e.preventDefault();
    }
  };
})();

Because the click happens on all the elements in the list, all you need to do is compare the nodeName to the right element that you want to react to the event.

Disclaimer: while both of the event examples above work in browsers, they fail in IE6. For IE6, you need to apply an event model other than the W3C one, and this is why we use libraries for these tricks.

The benefits of this approach are more than just being able to use a single event handler. Say, for example, you want to add more links dynamically to this list. With event delegation, there is no need to change anything; with simple event handling, you would have to reassign handlers and re-loop the list.

Anonymous Functions And The Module Pattern Link

One of the most annoying things about JavaScript is that it has no scope for variables. Any variable, function, array or object you define that is not inside another function is global, which means that other scripts on the same page can access—and will usually override— them.

The workaround is to encapsulate your variables in an anonymous function and call that function immediately after you define it. For example, the following definition would result in three global variables and two global functions:

var name = 'Chris';
var age = '34';
var status = 'single';
function createMember(){
  // [...]
}
function getMemberDetails(){
  // [...]
}

Any other script on the page that has a variable named status could cause trouble. If we wrap all of this in a name such as myApplication, then we work around that issue:

var myApplication = function(){
  var name = 'Chris';
  var age = '34';
  var status = 'single';
  function createMember(){
    // [...]
  }
  function getMemberDetails(){
    // [...]
  }
}();

This, however, doesn't do anything outside of that function. If this is what you need, then great. You may as well discard the name then:

(function(){
  var name = 'Chris';
  var age = '34';
  var status = 'single';
  function createMember(){
    // [...]
  }
  function getMemberDetails(){
    // [...]
  }
})();

If you need to make some of the things reachable to the outside, then you need to change this. In order to reach createMember() or getMemberDetails(), you need to return them to the outside world to make them properties of myApplication:

var myApplication = function(){
  var name = 'Chris';
  var age = '34';
  var status = 'single';
  return{
    createMember:function(){
      // [...]
    },
    getMemberDetails:function(){
      // [...]
    }
  }
}();
// myApplication.createMember() and 
// myApplication.getMemberDetails() now works.

This is called a module pattern or singleton. It was mentioned a lot by Douglas Crockford and is used very much in the Yahoo User Interface Library YUI5. What ails me about this is that I need to switch syntaxes to make functions or variables available to the outside world. Furthermore, if I want to call one method from another, I have to call it preceded by the myApplication name. So instead, I prefer simply to return pointers to the elements that I want to make public. This even allows me to shorten the names for outside use:

var myApplication = function(){
  var name = 'Chris';
  var age = '34';
  var status = 'single';
  function createMember(){
    // [...]
  }
  function getMemberDetails(){
    // [...]
  }
  return{
    create:createMember,
    get:getMemberDetails
  }
}();
//myApplication.get() and myApplication.create() now work.

I've called this "revealing module pattern6."

Allowing For Configuration Link

Whenever I've written JavaScript and given it to the world, people have changed it, usually when they wanted it to do things that it couldn't do out of the box—but also often because I made it too hard for people to change things.

The workaround is to add configuration objects to your scripts. I've written about JavaScript configuration objects in detail7, but here's the gist:

  • Have an object as part of your whole script called configuration.
  • In it, store all of the things that people will likely change when they use your script:
    • CSS ID and class names;
    • Strings (such as labels) for generated buttons;
    • Values such as "number of images being displayed," "dimensions of map";
    • Location, locale and language settings.
  • Return the object as a public property so that people can override it.

Most of the time you can do this as a last step in the coding process. I've put together an example in "Five things to do to a script before handing it over to the next developer8."

In essence, you want to make it easy for people to use your code and alter it to their needs. If you do that, you are much less likely to get confusing emails from people who complain about your scripts and refer to changes that someone else actually did.

Interacting With The Back End Link

One of the main things I learned from all my years with JavaScript is that it is a great language with which to make interactive interfaces, but when it comes to crunching numbers and accessing data sources, it can be daunting.

Originally, I learned JavaScript to replace Perl because I was sick of copying things to a cgi-bin folder in order to make it work. Later on, I learned that making a back-end language do the main data churning for me, instead of trying to do all in JavaScript, makes more sense with regard to security and language.

If I access a Web service, I could get JSON-P as the returned format and do a lot of data conversion on the client, but why should I when I have a server that has a richer way of converting data and that can return the data as JSON or HTML… and cache it for me to boot?

So, if you want to use AJAX, learn about HTTP and about writing your own caching and conversion proxy. You will save a lot of time and nerves in the long run.

Browser-Specific Code Is A Waste Of Time. Use Libraries! Link

When I started Web development, the battle between using document.all and using document.layers as the main way to access the document was still raging. I chose document.layers because I liked the idea of any layer being its own document (and I had written more than enough document.write solutions to last a lifetime). The layer model failed, but so did document.all. When Netscape 6 went all out supporting only the W3C DOM model, I loved it, but end users didn't care. End users just saw that this browser didn't show the majority of the Internets correctly (although it did)—the code we produced was what was wrong. We built short-sighted code that supported a state-of-the-art environment, and the funny thing about the state of the art is that it is constantly changing.

I've wasted quite some time learning the ins and outs of all of the browsers and working around their issues. Doing this back then secured my career and ensured that I had a great job. But we shouldn't have to go through this trial by fire any longer.

Libraries such as YUI, jQuery and Dojo are here to help us with this. They take on the problems of browsers by abstracting the pains of poor implementation, inconsistencies and flat-out bugs, and relieve us of the chore. Unless you want to beta test a certain browser because you're a big fan, don't fix browser issues in your JavaScript solutions, because you are unlikely to ever update the code to remove this fix. All you would be doing is adding to the already massive pile of outdated code on the Web.

That said, relying solely on libraries for your core skill is short-sighted. Read up on JavaScript, watch some good videos and tutorials on it, and understand the language. (Tip: closures are God's gift to the JavaScript developer.) Libraries will help you build things quickly, but if you assign a lot of events and effects and need to add a class to every HTML element in the document, then you are doing it wrong.

Resources Link

In addition to the resources mentioned in this article, also check out the following to learn more about JavaScript itself:

  • Douglas Crockford on JavaScript
    An in-depth video Lecture series.
  • The Opera Web Standards Curriculum>
    With a detailed section on JavaScript.

You may be interested in the following related posts:

(al)

Footnotes Link

  1. 1 http://json.org
  2. 2 http://www.javascriptkit.com/javatutors/arraysort.shtml
  3. 3 http://www.wait-till-i.com/2007/06/28/shortening-javascripts-with-math/
  4. 4 http://icant.co.uk/sandbox/eventdelegation/
  5. 5 http://developer.yahoo.com/yui
  6. 6 http://www.wait-till-i.com/2007/08/22/again-with-the-module-pattern-reveal-something-to-the-world/
  7. 7 http://www.wait-till-i.com/2008/05/23/script-configuration/
  8. 8 http://www.wait-till-i.com/2008/02/07/five-things-to-do-to-a-script-before-handing-it-over-to-the-next-developer/
  9. 9 https://www.smashingmagazine.com/2010/02/22/the-seven-deadly-sins-of-javascript-implementation/
  10. 10 https://www.smashingmagazine.com/2010/02/10/some-things-you-should-know-about-ajax/
  11. 11 https://www.smashingmagazine.com/2010/01/12/45-powerful-css-javascript-techniques/
SmashingConf Barcelona 2016

Hold on, Tiger! Thank you for reading the article. Did you know that we also publish printed books and run friendly conferences – crafted for pros like you? Like SmashingConf Barcelona, on October 25–26, with smart design patterns and front-end techniques.

↑ Back to top Tweet itShare on Facebook

Advertisement

Chris is a Developer Evangelist living in London, England, who writes about Javascript development, accessibility, and all things open web. After several years evangelizing at Mozilla Foundation, he's now working at Microsoft's EdgeDev team.

  1. 1

    I’m not even bothered to read this as I’ve seen this similar post title on way too many occasions. It’s starting to annoy me now.

    -10
  2. 2

    It’s obvious that the writer of this article has no idea about javascript programming and coding. What works in theory rarely works in practice. Smashing Magazine strikes again – this is a boring and useless article. As usual.

    -58
  3. 3

    var numbers = [3,342,23,22,124];
    var max = Math.max.apply( null, numbers ); //342
    do the job as well (via http://ejohn.org/blog/fast-javascript-maxmin/ ).

    4
  4. 4

    Vitaly Friedman (Smashing Editorial)

    April 20, 2010 6:40 am

    I would highly recommend to read the article first before publishing such comments. We appreciate constructive criticism, but what you are writing here is just wrong. Please read at least the introduction and the biography of the writer – he knows exactly what he is talking about.

    Sorry, XLS, but it’s really sad to receive such comments over and over again.

    23
  5. 5

    It’s ridiculous how some readers believe that smashing magazine and especially web design should be all about fancy graphics, visual inspiration and cuddly icons. As soon as you post something useful about web development or coding topics all this whiners (or wieners?) appear and leave their retarded comments about how bad smashing magazine got lately.
    I’m one of those users who appreciate the effort of each article and i’m sure that the content is always in some kind of way useful.
    Excuse my french, but go and watch teletubbies you f*tards, you are not worth it and you are far from being professional with such an attitude.
    At Smashing Magazine: Please mind that most of your readers who are satisfied and happy won’t leave any comment at all. Constructive critisism is a lot different from this and i’m sure that it appreciated by you. Keep up the good work.

    3
  6. 6

    Good article.

    For the module pattern, you can also encapsulate your application in an object, instead of a function. So instead of


    var myApplication = function(){
    var name = 'Chris';
    var age = '34';
    var status = 'single';
    function createMember(){
    // [...]
    }
    function getMemberDetails(){
    // [...]
    }
    }();

    we can have


    var myApplication = {
    name : 'Chris',
    age : '34',
    status : 'single',
    createMember : function () {
    // [...]
    }
    getMemberDetails : function (){
    // [...]
    }
    }

    Of course, this does involve refactoring the code more but you don’t have to return functions.

    1
  7. 7

    Willem Mulder

    April 20, 2010 7:55 am

    Excellent example. The Apply functions deserves a place in this article as well…
    Along with Arguments and Prototype.

    One could then for example define
    Array.prototype.max = function() {
    return Math.max.apply(null,this);
    }
    so that [1,3,4,45,2].max() would return 45…!

    4
  8. 8

    I’m glad Christian has written another article for SM, but I’m afraid I have a couple of critical points to share.

    Firstly, JSON is not the same as JavaScript’s object notation — sure, it’s a subset, but JSON is simply a data-interchange format. When you create an object literal and fill it with a bunch of properties you’re not creating JSON — that’s just an object. It’s quite a fuzzy topic, but I think you’ll find that there is some validity to my argument: http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/

    I think it’s important to maintain a high standard when it comes to nomenclature. It’s not called “ternary notation”; it’s the “ternary operator”, or more correctly, the “conditional operator”. It happens to be the only operator in JS that accepts three operands, and that’s why it’s commonly referenced as the “ternary operator”. Also, the Math object is not a function, it’s a regular object that contains a bunch of “static” methods, like “abs”, “floor” and “max”.

    I was surprised to see an entire section dedicated to Event Delegation, and not a single utterance of the words “bubbling” or “propagation” — If I was teaching Event Delegation I would start by explaining the fundamentals of DOM events, including how events bubble, and possibly discussing event capturing too.

    Oh, also, finding the largest number in an array of numbers is EVEN simpler than you’re supposed ne plus ultra. E.g. Math.max.apply(null, [3,342,23,22,124]) === 342 ….

    4
  9. 9

    I read the article and didn’t see where you’re basing your judgment on. Also, this is geared towards beginners and intermediate developers, so if you’re a JS expert and didn’t see anything particularly new, you shouldn’t be surprised.

    On a different topic: @chris heilmann – it would be fun to see an article on JavaScript scripting performance/optimization techniques. I just read a blog post by Nicholas Zakas that he wrote last year that made me go “aha” about optimizing loops by iterating on the items in chunks. I mean, the solution is so simple that you scratch your head and think, “Why haven’t I thought of that?” Even “basic” stuff such as declaring local variables when you access global variables more than once in your script would be a great read for people.

    1
  10. 10

    Thank you Smashing Magazine for this article!! It’s great! And all those people (@Marin, @Robbie, @XLS, etc.) whining about the articles, so what if every article doesn’t meet your needs.

    Why don’t you enlighten all of us with your vast knowledge on these subjects? I’d love to learn from an expert like you! Or maybe you have no clue what you’re talking about…

    0
  11. 11

    Andrew Hedges

    April 20, 2010 9:09 am

    Excellent article, Chris. One minor point is your array sort function will fail in some rare edge cases. I have a write up here: http://hurl.ws/1mln

    I have to think some of the negative comments here are either trolls or the work of emotionally immature people. This article is a great introduction to some key concepts that would have helped me heaps early on in my career.

    2
  12. 12

    I can second you on the shorthand “techniques” and native functions. I’ve spent lots of time trying to figure out the fastest way to do something, and then someone telling me afterwards that JS “will do that for you…*blank stare*”.

    Anyways, good article. :)

    2
  13. 13

    Marin Todorov

    April 20, 2010 6:31 am

    Very disappointed with the quality of articles in Smashing lately …
    After the Hello world! in PHP, now comes a Hello world! in Javascript.

    Excellently written article btw, great for an introduction to javascript

    3
  14. 14

    Smashing Editorial

    April 20, 2010 6:42 am

    As you know, Marin, we are aiming for a variety of articles on very different topics. Could you please be more specific – what recent articles are you disappointed with?

    3
  15. 15

    The “revealing module pattern” idea is cool :)

    0
  16. 16

    Bart de Bruin

    April 20, 2010 7:01 am

    Well i think its a good article for people with not much js experience (like myself).
    Always good to learn new stuff

    thnx Chris.

    1
  17. 17

    Much better article than the usual “Let’s learn jQuery!” article usually posted here. Here’s hoping some of the people who rely exclusively on libraries with no understanding of what they do take an interest in this article.

    0
  18. 18

    Anonymous functions are not JavaScript 101. I really enjoyed the article’s focus on JavaScript design patterns. I would even suggest going even deeper into JavaScript.

    Great Article!

    0
  19. 19

    chris heilmann

    April 20, 2010 7:09 am

    Needs citation.

    3
  20. 20

    Indeed, poor article. An example:

    Take “Math.max(12,123,3,2,433,4)”, this piece of code is often useless since it uses a constant list of arguments. Most people would assume the max function also accepts an array, after all, this is JavaScript we are talking about. So try “Math.max([12,123,3,2,433,4])”, it returns NaN. This would be a great start to explain how functions work in JS: “Math.max.apply(null, [12,123,3,2,433,4])”.

    Now THAT is some I wish I knew much earlier—not that Math.max exists.

    The example before contradicts this. OK, it perfectly demonstrates the use of a lambda method to sort an array in descending order and pick the first element as “max” (BTW: what if the array is empty?), but why not simply use Math.max? Maybe because it does not accept arrays?

    0

↑ Back to top