Mark Daggett's Blog

Innovator & Bricoleur

Introducing Expert JavaScript

As many of you know I have spent much of the last six months writing a book on JavaScript. I am pleased to announce that last week APress began shipping it out to stores and distribution centers everywhere.

In my mind, good technical books are part mixtape, treasure map, and field journal. "Expert JavaScript" is the result of my efforts to successfully weave these forms together into a compelling and information-rich book about JavaScript. A mixtape, for those old enough to remember, is a curated collection of songs. These tapes were often made as gifts for friends, lovers, and those in between. The mixer would craft the tape by selecting personal favorites or organizing tracks along a conceptual thread. Often these tapes were a surrogate for the mixer, a way to be remembered by the listener when the tape was playing. This book is a mixtape for JavaScript that I made for you. These chapters cover some of my favorite aspects of the language, but also includes less-understood topics because they are not easily explained in a tweet or blog post. The long form format of a book affords these subjects the necessary room to breathe.

As a child, I found the idea of finding a treasure map a thrilling prospect. I was captivated by the idea that anyone could become rich as long as they followed the map. This book will not lead you to buried treasure, but it is a map of sorts. I laid out these chapters to chart the inner workings of the language, which you can follow to the end. Dig through these concepts with me and you will unearth a deeper understanding of JavaScript than when you started.

A field journal is kept by scientists. They are taught to keep a log of their thoughts, observations, and hunches about their subject. They may even tape leaves, petals, or other artifacts of nature between its pages. It’s a highly contextual diary about a subject of study filtered through a specific point of view. The purpose of the field journal is to be a wealth of information that the scientist can continually mine when they are no longer in the field.

"Expert JavaScript" is my field journal of JavaScript, which I wrote to return to often. I will use it to help me remember and understand the particulars of the language. I encourage you to do the same. Scribble in the margins, highlight sections, and bookmark pages. It is not a precious object; it is meant to be a living document that is improved through your use.

Table Of Contents (with comments)

  • Chapter 1: Objects and Prototyping (What JavaScript is and isn’t)
  • Chapter 2: Functions (Deep dive into functions including changes in es6)
  • Chapter 3: Getting Closure (Understanding the dark arts of closures)
  • Chapter 4: Jargon and Slang (lexical border guards to the community)
  • Chapter 5: Living Asynchronously (promises, coroutines, webworkers)
  • Chapter 6: JavaScript IRL (nodebots, JohnnyFive, node-serialport, firmata )
  • Chapter 7: Style (understanding programmatic style)
  • Chapter 8: Workflow (sensible workflow for JavaScript developers)
  • Chapter 9: Code Quality (how to evaluate and improve quality in code)
  • Chapter 10: Improving Testability (what really makes code "untestable," hint it’s not the code)

Functional Illiteracy in JavaScript

When someone cannot read or write in their native language, they are considered functionally illiterate. This level of illiteracy means that they subsist in their daily life through their ability to speak fluently, and recognize certain written keywords. Illiteracy is not a sign of stupidity; in many cases it is the result a lack of opportunity to learn. However, illiteracy does stunt the potential of otherwise bright people. The sad fact is their inability to participate in society through the mastery of language makes them at higher risk of being in poverty and committing crime.

Most computer languages are written, not spoken (try speaking JavaScript out loud and you’ll see what I mean). Therefore, being able to write code does not make you literate. Being an illiterate developer means that you skim across the surface of the language, copying snippets of code from others trying cobble, together a working program with little or no understanding of how or why it works.

As with illiterates in the wider world, illiterate developers are not unintelligent. Often it means that they didn’t have the luxury of taking a deep dive through the mechanics of the programming language. Many illiterate developers are practicing software professionals, backed into a corner by impending deadlines, or lack of resources. Perhaps they started in other fields such as graphic design, or business and find themselves scurrying along the surface of the language, learning in fits and starts as they go along.

Dynamic Spotlight Effect Using CSS and JavaScript

In casual gaming there is a convention whereby the player is introduced to the interface during the first play cycle. Typically, this involves a character from the game pointing out aspects of the interface and telling the player how to use it and why they should care. Ideally, you want to visually draw the attention of the player to the relevant component of the interface as the characters are explaining it. For this purpose I created a JavaScript class which will spotlight a portion of the screen using only CSS and JavaScript. Here is an example of it working.

The class allows you to configure the following spotlight attributes:

  • starting x,y (integer)
  • destination x,y (integer)
  • duration (0%-100%)
  • callback when animation is complete (function)

Below is the CSS and JavaScript you’ll need to use it in your own projects. If you improve this script please let me know.

1
<div id="spotLight"></div>
1
2
3
4
5
6
7
#spotLight {
  width:1024px;
  height:768px;
  z-index:9;
  position:absolute;
  display:none;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
function SpotLight(element) {
  this.element = element;
  this.x = element.width() / 2;
  this.y = element.height() / 2;
  this.show = function() {
    element.hide();
    element.removeClass("hide");
    return element.fadeIn('fast');
  };
  this.hide = function(callback) {
    element.fadeOut('fast', function() {
      if (callback) {
        return callback();
      }
    });
    return element.addClass("hide");
  };
  this.move = function(opts) {
    var endX, endY, obj;
    obj = $.extend({}, {
      start_x: this.x,
      start_y: this.y,
      x: this.x,
      y: this.y,
      aperture: "50%",
      duration: 1000,
      done: function() {}
    }, opts);
    endX = obj.x;
    endY = obj.y;
    obj.x = obj.start_x;
    obj.y = obj.start_y;
    return jQuery(obj).animate({
      x: endX,
      y: endY
    }, {
      duration: obj.duration,
      step: function() {
        var style, _i, _len, _ref;
        _ref = ["-moz-radial-gradient(" + this.x + "px " + this.y + "px, ellipse cover,  rgba(0,0,0,0) 0%, rgba(0,0,0,0.8) " + this.aperture + ", rgba(0,0,0,0.8) 100%)", "-webkit-gradient(radial, " + this.x + "px " + this.y + "px, 0px, " + this.x + "px " + this.y + "px, 100%, color-stop(0%,rgba(0,0,0,0)), color-stop(" + this.aperture + ",rgba(0,0,0,0.8)), color-stop(100%,rgba(0,0,0,0.8)))", "-webkit-radial-gradient(" + this.x + "px " + this.y + "px, ellipse cover,  rgba(0,0,0,0) 0%,rgba(0,0,0,0.8) " + this.aperture + ",rgba(0,0,0,0.8) 100%)", "-o-radial-gradient(" + this.x + "px " + this.y + "px, ellipse cover,  rgba(0,0,0,0) 0%,rgba(0,0,0,0.8) " + this.aperture + ",rgba(0,0,0,0.8) 100%)", "-ms-radial-gradient(" + this.x + "px " + this.y + "px, ellipse cover,  rgba(0,0,0,0) 0%,rgba(0,0,0,0.8) " + this.aperture + ",rgba(0,0,0,0.8) 100%)", "radial-gradient(ellipse at " + this.x + "px " + this.y + "px,  rgba(0,0,0,0) 0%,rgba(0,0,0,0.8) " + this.aperture + ",rgba(0,0,0,0.8) 100%)"];
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          style = _ref[_i];
          element.css({
            "background": style
          });
        }
        return true;
      },
      done: obj.done
    });
  };
  return this;
}

// Example Usage:
var spotLight = new SpotLight($("#spotLight"))
spotLight.show();
spotLight.move({ x: 150, y: 650 });

Racing and Profiling

I’ve been experimenting with various ways to profile, and explore JavaScript as it executes in the runtime environment. Mostly I’ve been experimenting with the rKelly and rubyracer gems. Both gems are written by people much smarter than myself so there is lots to learn and explore inside their source. I was talking to the very friendly Charles Lowell, creator of the rubyracer and he shared this great snippet with me, which allows you to turn on the v8 profiler while the rubyracer is running. Because this is an undocumented hook I thought I’d share it here:

1
ruby -Ilib -Iext -rv8 -e 'V8::C::V8::SetFlagsFromString("--prof"); V8::Context.new() {|c| puts c.eval("5 + 1")}; V8::C::V8::PauseProfiler()'

This will produce a v8.log file wherever you executed the script from. Inside the file there is a gluttonous amount of data, which will take some time to parse through but in general it looks a bit like this:

code-creation,LoadIC,0x127fc3e29140,181,"A load IC from the snapshot"
code-creation,KeyedLoadIC,0x127fc3e29200,181,"A keyed load IC from the snapshot"
code-creation,StoreIC,0x127fc3e292c0,183,"A store IC from the snapshot"
code-creation,KeyedStoreIC,0x127fc3e29380,183,"A keyed store IC from the snapshot"
code-creation,Builtin,0x127fc3e29440,97,"A builtin from the snapshot"
code-creation,Builtin,0x127fc3e294c0,137,"A builtin from the snapshot"
code-creation,Script,0x127fc3e14e20,980,"native string.js",0x2e87cc50ec50,
code-creation,LazyCompile,0x127fc3e15500,1616,"SetUpString native string.js:940",0x2e87cc5129c8,
code-creation,LazyCompile,0x127fc3e15be0,472," native string.js:36",0x2e87cc512ab0,
code-creation,Script,0x127fc3e15dc0,336,"native array.js",0x2e87cc512e00,
code-creation,LazyCompile,0x127fc3e15f20,2544,"SetUpArray native array.js:1469",0x2e87cc5175b0,
code-creation,LazyCompile,0x127fc3e16920,340,"SetUpArray.b native array.js:1482",0x2e87cc517668,
code-creation,Script,0x127fc3e16b00,552,"native regexp.js",0x2e87cc5177f0,
code-creation,LazyCompile,0x127fc3e16d40,388,"RegExpConstructor native regexp.js:86",0x2e87cc518a70,
code-creation,LazyCompile,0x127fc3e16ee0,280,"RegExpMakeCaptureGetter native regexp.js:363",0x2e87cc519288,
code-creation,LazyCompile,0x127fc3e17000,668," native regexp.js:364",0x2e87cc519340,
code-creation,LazyCompile,0x127fc3e172a0,2304,"SetUpRegExp native regexp.js:403",0x2e87cc519488,
code-creation,LazyCompile,0x127fc3e17ba0,292,"SetUpRegExp.a native regexp.js:422",0x2e87cc519540,
code-creation,LazyCompile,0x127fc3e17ce0,256,"SetUpRegExp.c native regexp.js:426",0x2e87cc519658,

Javascript ParseTrees

I’ve been experimenting with the rkelly Ruby gem to help me explore the JavaScript parse tree. It is really fascinating, and I can see myself spending a lot of time spelunking through the language. Here is a simple example using the gem to iterate over each node in the parse tree and print out its type. Stay tuned, more to come!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
require 'rubygems'
require 'rkelly'
parser = RKelly::Parser.new
src = <<EOF
// Create scrollLeft and scrollTop methods
jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
  var top = "pageYOffset" === prop;

  jQuery.fn[ method ] = function( val ) {
    return jQuery.access( this, function( elem, method, val ) {
      var win = getWindow( elem );

      if ( val === undefined ) {
        return win ? win[ prop ] : elem[ method ];
      }

      if ( win ) {
        win.scrollTo(
          !top ? val : window.pageXOffset,
          top ? val : window.pageYOffset
        );

      } else {
        elem[ method ] = val;
      }
    }, method, val, arguments.length, null );
  };
});

function getWindow( elem ) {
  return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
}
EOF
ast = parser.parse(src)

=begin
Outputs something like this as it traverses the parseTree
RKelly::Nodes::SourceElementsNode
RKelly::Nodes::ExpressionStatementNode
RKelly::Nodes::FunctionCallNode
RKelly::Nodes::DotAccessorNode
RKelly::Nodes::ResolveNode
RKelly::Nodes::ArgumentsNode
RKelly::Nodes::ObjectLiteralNode
RKelly::Nodes::PropertyNode
...
=end

ast.each do |node|
  puts node.class
end

Getting Closure

Understanding the Dark Arts of JavaScript Closures

"No matter where you go, there you are." - Buckaroo Banzai

The purpose of this post is to explain how closures work in plain english, and to give a few compelling examples where the use of closures really improve the quality of your code.

Like many others I am a self-taught programmer, and little over a decade ago I was also a freshly minted Creative Director working in Los Angels. I was employed by a major footwear brand, and had inherited a team of very bright and technically gifted programmers. I felt that I needed to learn enough code to speak intelligently to them. I didn’t want to propose a feature that wasn’t possible, and more importantly I wanted to understand the promise and the problems inherent in the medium we were building within. More generally though, I am just a very curious person who likes to learn. Once I started to pull that tread the world of programming began to unwind for me. Now years later, here I sit writing about the internals of JavaScript.

Being that my computer science education has been ad-hoc there are many core concepts in JavaScript (and programming in general) that I wanted to understand better. My hypothesis is that there are others like me who have been using and abusing JavaScript for years. For this reason I decided to write on closures an often used but equally often misunderstood concept in JavaScript. Closures are important for a variety of reasons:

  1. They are both a feature and a philosophy that once understood makes many other concepts (e.g. data binding, promise objects) in JavaScript easier.
  2. They are one of the most powerful internals of the language, which many other so-called real languages don’t support.
  3. They are where JavaScript is trending due to the rise in popularity of asynchronous execution.

For all the potential benefits that closures offer, there is a black magic quality to them that can make them hard to understand. Let’s start with a definition, A closure is the act of binding all free variables, and functions into a closed expression, that persist beyond the lexical scope from which they were created. While this is a succinct definition it is pretty impenetrable for the uninitiated; let’s dig deeper.

The Straight Dope On Scope

Before we can truly understand closures we must take a step back and look at how scope works in JavaScript. When reading about JavaScript periodically writers will make reference to lexical scope, or the current and/or executing scope. Lexical scope simply means that where a statement is placed within the body of the script is important and effects how it can be accessed, and what in turn it has access to. In JavaScript unlike other languages the only way to create a new scope is through a function invocation [1]. This is what programmers mean when they say JavaScript has function level scoping. This form of scoping may be anti-intuitive to programmers coming from languages that support block-level scoping e.g. Ruby.

The following example demonstrates lexical scope:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Free Variable
var iAmFree = 'Free to be me!';

function canHazAccess(notFree){

  var notSoFree = "i am bound to this scope";

  // => "Free to be me!"
  console.log(iAmFree);
}

// => ReferenceError: notSoFree is not defined
console.log(notSoFree)

canHazAccess();

As you can see the function declaration canHazAccess() can reference the iAmFree variable; this is because the variable belongs to the enclosing scope. The iAmFree variable is an example of what in JavaScript is called a free variable [2]. Free variables are any non-local variable which the function body has access to. To qualify as a free variable it must be defined outside the function body and not be passed as a function argument.

Conversely, we see that referencing notSoFree from the enclosing scope produces an error. This is because at the point at which this variable was defined it was inside a new lexical scope (remember function invocation creates a new scope).

Put another way, function level scopes act like one-way mirrors; they let elements inside the function body spy on variables in the outer scope, while they remain hidden. As we’ll see below closures short-circuit this relationship, and provide a mechanism whereby the inner scopes internals can be accessed by the outer scope.

Thisunderstandings

One feature of scopes, that routinely throw developers off (even seasoned ones) is the use of the this keyword as it pertains to the lexical scope. In JavaScript the this keyword always refers to the owner of scope from which it is executing. Misunderstanding how this works can cause all sorts of weird errors where a developer assumes they are accessing a particular scope but are actually using another. Here is how this might happen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var Car, tesla;

Car = function() {
  this.start = function() {
    console.log("car started");
  };

  this.turnKey = function() {
    var carKey = document.getElementById('car_key');
    carKey.onclick = function(event) {
      this.start();
    };
  };
  return this;
};
tesla = new Car();

// Once a user click's the #carKey element they will see "Uncaught TypeError: Object  has no method 'start'"
tesla.turnKey();

The developer who wrote this was headed in the right direction, but ultimately a thisunderstanding forced them off the rails. They correctly bound the click event to the car_key DOM element. However, they assumed that nesting the click binding inside the car class would give the DOM element a reference to the car’s this context. The approach is intuitive and looks legit, especially based on what we know about free variables and lexical scope. Unfortunately, it’s hopelessly borked; because as we learned earlier a new scope is created each time a function is invoked. Once the onclick event fired this now referred to the DOM element not the car class.

Developers sometimes get around this scoping confusion by assigning this to a local free variable (e.g. that, _this, self, me). Here is the previous method rewritten to use a local free variable instead of this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var Car, tesla;

Car = function() {
  this.start = function() {
    console.log("car started");
  };

  this.turnKey = function() {
    var that = this;
    var carKey = document.getElementById('carKey');
    carKey.onclick = function(event) {
      that.start();
    };
  };
  return this;
};
tesla = new Car();

// Once a user click's the #carKey element they will see "car started"
tesla.turnKey();

Because that is a free variable, it won’t be redefined when the onclick event is triggered. Instead it remains as a pointer to the previous this context. Technically, this solves the problem, and I am going to resist the urge of calling this an anti-pattern (for now). I have used this technique thousands of times over the years. However, it always felt like a hack, and fortunately, closures can help us marshall scopes in a much more elegant way.

My First Closure

In it’s most basic form a closure is simply an outer function that returns an inner function. Doing this creates a mechanism to return an enclosed scope on demand. Here is a simple closure:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function outer(name) {
  var hello = "hi",
  inner;

  return inner = function() {
    return hello + " " + name;
  }
}

// Create and use the closure
var name = outer("mark")();

// => 'hi mark'
console.log(name);

In this example you can see that the local variable hello can be used in the return statement of the inner function. At the point of execution hello is a free variable belonging to the enclosing scope. This example borders on meaninglessness though; lets look at a slightly more complex closure:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var car;
function carFactory(kind) {
  var wheelCount, start;
  wheelCount = 4;
  start = function() {
    console.log('started with ' + wheelCount + ' wheels.');
  };

  // Closure created here.
  return (function() {
    return {
      make: kind,
      wheels: wheelCount,
      startEngine: start
    };
  }());
}

car = carFactory('Tesla');

// => Tesla
console.log(car.make);

// => started with 4 wheels.
car.startEngine();

Why Use Closures

Now that we know what closures are, let’s look at some use cases on where they can elegantly solve common problems in JavaScript.

  • Object Factories

    The previous closure implements what is commonly known as the Factory Pattern [3]. In keeping with a Factory Pattern the internals of the factory can be quite complex but are abstracted away in part thanks to the closure. This highlights one of the best features of closures which is their ability to hide state. JavaScript doesn’t have the concept of private or protected contexts, but using closures give us a good way to emulate some level of privacy.

  • Create A Binding Proxy

    As promised lets revisit the Car class we wrote earlier. We solved the scoping problem by assigning the outer function’s this reference to a that free variable. Instead of that approach we’ll solve it through the use of closures. First we create a reusable closure function called proxy, which takes a function and a context and returns a new function with the supplied context applied. Then we wrap the onclick function with our proxy and pass in the this that references the current instance of the Car class. Coincidentally, this is a simplified version of what jQuery does in their own proxy function [4].

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    var Car, proxy, tesla;
    
    Car = function() {
      this.start = function() {
        return console.log("car started");
      };
      this.turnKey = function() {
        var carKey;
        carKey = document.getElementById("carKey");
        carKey.onclick = proxy(function(event) {
          this.start();
        }, this);
      };
      return this;
    };
    
    // Use a closure to bind the outer scope's reference to this into the newly created inner scope.
    proxy = function(callback, self) {
      return function() {
        return callback.apply(self, arguments);
      };
    };
    
    tesla = new Car();
    
    // Once a user click's the #carKey element they will see "car started"
    tesla.turnKey();
    
  • Contextually Aware DOM Manipulation

    This example comes from directly from Juriy Zaytsev’s excellent article "Use Cases for JavaScript Closures" [5] . His example code demonstrates how to use a closure to ensure a DOM element has a unique ID. The larger takeaway is that you can use closures as a way to maintain internal states about your program in an encapsulated manner.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    var getUniqueId = (function() {
      var id = 0;
      return function(element) {
        if (!element.id) {
          element.id = 'generated-uid-' + id++;
        }
        return element.id;
      };
    })();
    
    var elementWithId = document.createElement('p');
    elementWithId.id = 'foo-bar';
    var elementWithoutId = document.createElement('p');
    
    // => 'foo-bar'
    getUniqueId(elementWithId);
    
    // => 'generated-id-0'
    getUniqueId(elementWithoutId);
    
  • Singleton Module Pattern

    Modules are used to encapsulate and organize related code together under one roof. Using modules keeps your codebase cleaner, easier to test, and reuse. Attribution for the Module Pattern is typically given to Richard Conford [6], though a number of people most notably Douglas Crockford are responsible for popularizing it. The Singleton Module is a flavor that restricts more than one instance of the object from existing. It is very useful for instances where you want several objects to share a resource. A much more in depth example of the Singleton Module can be found here [7], but for now consider the following example:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    // Create a closure
    var SecretStore = (function() {
      var data, secret, newSecret;
    
      // Emulation of a private variables and functions
      data = 'secret';
      secret = function() {
        return data;
      }
      newSecret = function(newValue) {
        data = newValue;
        return secret();
      }
    
      // Return an object literal which is the only way to access the private functions and variables
      return {
        getSecret: secret,
        setSecret: newSecret,
      };
    })();
    
    var secret = SecretStore;
    
    // => "secret"
    console.log(secret.getSecret());
    
    // => "foo"
    console.log(secret.setSecret("foo"));
    
    // => "foo"
    console.log(secret.getSecret());
    
    var secret2 = SecretStore;
    
    // => "foo"
    console.log(secret2.getSecret());
    

TLDR Takeaways

  1. Lexical scope gives importance to where code is located within the script body.
  2. Free variables are any non-local variable which the function body has access to.
  3. The only way for new scopes to be created in JavaScript is through function invocation.
  4. The *this* keyword always refers to the owner of scope from which it is executing.
  5. A closure allows a function to access variables outside of its lexical scope.
[1]http://howtonode.org/what-is-this
[2]http://en.wikipedia.org/wiki/Free_variable
[3]http://en.wikipedia.org/wiki/Factory_method_pattern
[4]https://github.com/jquery/jquery/blob/master/src/core.js#L685
[5]http://msdn.microsoft.com/en-us/magazine/ff696765.aspx
[6]http://groups.google.com/group/comp.lang.javascript/msg/9f58bd11bd67d937
[7]http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript

CYA With CSS

Using Design Time Classes To Polish Your Product

This post is dedicated to CYA with CSS; for the uninitiated CYA means "cover your ass", and I assume that anyone reading my blog already knows what CSS is. Just as you can craft the JavaScript on your website to act defensively against unforeseen errors, so too can you use CSS at the design stage to ensure you don’t end up with egg on your face post-launch.

A while back, I was viewing the Github’s source code (man I sound like such a nerd), and I noticed these classes added to their body tags: "logged_in page-dashboard macintosh env-production". Several of these classes are obviously progressive enhancement style additions meant to change the layout / features of the page based on the visitor’s browser. In my own sites I often include the controller and action params into the body tag so that I can scope my JavaScript and CSS executions. Doing this provides a convenient way to namespace your CSS and JS, without having to worry about polluting the global namespace.

However one of Github’s additions stuck out at me "env-production". I have to imagine that Kyle Neath was the one who added this to the page, and that he did it because he wants the site to render differently based on the runtime environment of the sever.

I thought about the possibilities of this technique and figured out that there are probably a whole host of ways to use these design time classes. The use of which would help ensure a polished final project. Here are just a couple of examples of how you might use them:

1. If you are using a specific grid layout you could set an image to appear as a background-image of the body. Doing this would ensure your page conforms the the correct visual spacing and vertical rhythm. I know that "Blueprint CSS" used to have something like this back in the day. It might look something like this:

1
2
3
body.env-development {
  background: url('/assets/grid.png') no-repeat scroll top left !important;
}

2. Often as developers we’ll mock in a bit of functionality that the design calls for with the intention of making it work later. Unfortunately, this can mean that dead links get deployed. Here is how you could use a CSS selector and a design time class to color code all the links without a href attribute. This example adds a gaudy eye-searing color to all the dead links, to ensure you fix it before you deploy into production.

1
2
3
4
5
6
body.env-development {
  a:not([href]) {
    color:#00FF00 !important;
    background-color:#ff00ff !important;
  }
}

The best thing about design time classes is that because they are properly scoped to the body they just disappear in the production environment. This means you don’t have to worry about them being seen by the end user.

If you are using Rails it’s a pretty straight forward process to get these classes into your application.

1
%body{ :class => "#{app_classes}" }

In your application helper you’d add something like this:

1
2
3
def app_classes
  "#{Rails.env} #{params[:controller].gsub('/',' ')} #{params[:action]}"
end
  1. Kyle suggested over twitter that another good use is to change the favicon based on the server environment.

More To Come

Do you use Design time classes? If so what are they, share them in the comments or as a gist and maybe we can develop a nice resource of helpful snippets for others.

JavaScript Jigs

In the excellent book "The Pragmatic Programmer: From Journeyman to Master" Hunt and Thomas use the metaphor of a wood worker’s jig to describe how a smart programmer reduces the repetitive nature of coding by creating reusable templates or code generators:

"When woodworkers are faced with the task of producing the same thing over and over, they cheat. They build themselves a jig or a template. If they get the jig right once, they can reproduce a piece of work time after time. The jig takes away complexity and reduces the chances of making mistakes, leaving the craftsman free to concentrate on quality."

To be a jig the solution is highly specific and good for one task, for example making a complex cut. At first you might want to conflate jigs and design patterns together, because they are both reusable solutions to a problem. Jigs are precise where design patterns are generalized. While Hunt and Thomas said jigs are generators, I will use them in the context of helpers, friendly little functions or classes that do one thing well. Many of the most popular JavaScript libraries started as a collection of jigs. Prototype and JQuery for example, were initially just a collection of reusable snippets that acted like speed-boosts, and shortcuts for discrete problems.

What follows are a collection of jigs that are useful in modern JavaScript applications.

Self Executing Functions

The immediately invoked function expression (IIFE) is one jig you will see various libraries and frameworks use repeatedly. In its most basic form it can be written in a couple of ways

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
;(function(){
    ...
})();

;!function(){
    ...
}();

;-function(){
    ...
}();

;+function(){
    ...
}();

;~function(){
    ...
}();

// Not Recommended
;void function(){
    ...
}();

// Not Recommended
;delete function(){
    ...
}();

The beauty of the IIFE is that it uses a unary expression to coerce a function declaration, which would normally need to be explicitly called into a function expression that can self-execute. Behind the scenes JavaScript is running a unary operation on the function declaration, the result of that operation is the function expression, which is immediately invoked with the trailing parentheses "()". Besides being elegant code the IIFE also affords the following:

  • It provides a closure which prevents naming conflicts
  • It provides elegant block scoping
  • It prevents pollution of the global namespace.
  • It promotes the developer to think in terms of modular code.

One other point worth mentioning is the use of the semicolon prepending the statement. Adding this provides a bit of defensive programming against other malformed modules that might have a trailing semicolon. If this were just a function declaration it would be absorbed into the preceding module. This can often occur when multiple scripts are concatenated together as part of a deploy process. It is highly recommended that you follow this convention to protect yourself against mystery bugs in production.

Modules

Modules are very common is many programming languages, though JavaScript doesn’t have a native representation for them. As such other developers have developed a spec for encapsulating your code inside a reusable module. The following code is based off an example in the "Principles of Writing Consistent, Idiomatic JavaScript" [1].

There are a couple of elements that should be called out in this jig:

  • We see two different examples of the self executing function jig being used. This is to ensure proper closure around the module itself and the initializer function that adds it to the global namespace.
  • Invoking this function returns an object with a bound reference to the private variable "data". This allows the developer to enforce the use of getters and setters for access to the data variable.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
;!function(global) {
  var Module = (function() {

    // Mostly Private Variable
    var data = 'secret';

    return {

      bool: true,
      string: 'a string',
      array: [1, 2, 3, 4],
      object: {
        lang: "en-Us"
      },
      getData: function() {
        return data;
      },
      setData: function(value) {
        return (data = value);
      }
    };
  })();

  // expose our module to the global object
  global.Module = Module;

}(this);

safeEval

The eval function and its siblings setTimeout, setInterval and Function all have access to the JavaScript compiler, which means it is a bit like running with scissors. Since eval typically does more harm than good people try to work around it as much as possible. This jig does just that giving you eval like features without calling the function.

1
2
3
4
5
6
7
8
9
10
// A string representation of an a object similar to what you might get with JSON.
var dataString = '{"foo":"bar"}';

;!function(global, data){

    // the variable name provided is replaced with the evaluated code.
    global[data] = new Function("return" + global[data])()
}(this, "dataString");

// dataString is now Object {foo: "bar"}

PubSub

PubSub is short for a publish-subscribe message system, where objects ask to receive messages that are broadcast by publishers. The main advantage of PubSub is that the subscribers are loosely coupled allowing just about any object to publish and subscribe to messages. PubSub systems also have been proven to scale much nicer that tightly coupled client / server paradigms. This implementation of PubSub was written by Ben Alman and can be download from his Github account [2]. Let’s take a look at this jig in detail. Again, the first thing you should notice is that this jig uses the IIFE jig too (see a pattern yet?). This jig does depend on jQuery for access to the "on","off", and "trigger" functions. This jig stores an internal list of subscribers as keys of the internal object "o". When a message is broadcast all the subscribers have the arguments supplied by the publisher transferred to them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
;(function($) {

  var o = $({});

  $.subscribe = function() {
    o.on.apply(o, arguments);
  };

  $.unsubscribe = function() {
    o.off.apply(o, arguments);
  };

  $.publish = function() {
    o.trigger.apply(o, arguments);
  };

}(jQuery));

// Usage Examples
// Creates a "named" logging function.

function createLogger(name) {
  return function(event, a, b) {

    // Skip the first argument (event object) but log the name and other args.
    console.log(name, a, b);
  };
}

// Subscribe to the "foo" topic (bind to the "foo" event, no namespace).
$.subscribe('foo', createLogger('foo'));

// Subscribe to the "foo.bar" topic (bind to the "foo" event, "bar" namespace).
$.subscribe('foo.bar', createLogger('foo.bar'));

/*
 * logs:
 * foo 1 2
 * foo.bar 1 2
 * foo.baz 1 2
 */
$.publish('foo', [1, 2]);

/*
 * logs:
 * foo.bar 3 4
 */
$.publish('foo.bar', [3, 4]);

Your Jigs Go Here

Please send me your favorite jigs. I would love to expand this post with more great Jigs.

Functions Explained

A Deep Dive into JavaScript Functions

Based on my readership I have to assume most of you are familiar with JavaScript already. Therefore, it may seem odd to include a post on functions. After all, they are one of the most rudimentary components of JavaScript. My assertion is this, just as a person can speak a language without the ability to read or write it, so too can developers use functions in JavaScript and yet be blissfully unaware of their complexities.

Typically developers only become aware of the specifics of functions when something they wrote explodes in their face. My goal in this section is to expose the intricacies of JavaScript functions to you, which will hopefully save you from having to pull syntactic shrapnel from your codebase.

A word of caution before we begin; JavaScript is only as good as its interpreter. While the concepts we’ll consider are well-covered in the language spec, it does not mean that all runtime environments will work the same way. In other words your milage may vary. This section will discuss common misconceptions of JavaScript functions, and the silent bugs they introduce. However, debugging functions in detail is not covered. Fortunately, debugging has been documented by others in the JavaScript community especially in Juriy Zaytsev’s excellent article "Named Function Expressions Demystified" [1].

Blocks in JavaScript

Before we can understand functions in JavaScript we have to understand blocks. JavaScript blocks are nothing more than statements grouped together. Blocks start with a left curly bracket "{" and end with a right one "}". Simply put, blocks allow statements inside the brackets to be executed together. Blocks form the most basic control structure in JavaScript. The following are a few examples of how blocks in JavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Block as an anonymous self-executing function
;!function () {
    var triumph = false,
        cake = false,
        satisfaction = 0,
        isLie,
        note;

    // Block used as part of function expression
    var isLie = function (val) {
        return val === false;
    }

    // Block used as part of a conditional statement
    if (isLie(cake)) {
        triumph = true;
        makeNote('huge success');
        satisfaction += 10;
    }

    // Block used as part of a function declaration
    function makeNote(message) {
        note = message;
    }
}();

As we saw above, functions are essentially named blocks, which the developer can invoke on demand. This is easy to demonstrate:

1
2
3
4
5
6
7
8
9
10
11
12
// The inline conditional block statement is executed only once per cycle.
if (isLie(cake)) {
    ...
}

function makeNote(message) {
    ...
}

// The function declaration is executed as many times as it is called.
makeNote("Moderate Success");
makeNote("Huge Success");

Function Arguments

Functions like control flow statements (if, for, while etc.) can be initialized by passing arguments into the function body. In JavaScript variables are either a complex type (e.g. Object, Array) or a primitive type (e.g. String, Integer). When a complex object is supplied as an argument it is passed by reference to the function body. Instead of sending a copy of the variable, JavaScript sends a pointer to its location in memory. Conversely, when passing a primitive type to a function JavaScript passes by value. This difference can lead to subtle bugs because conceptually we often treat functions as a black box, and assume they can only effect the enclosing scope by returning a variable. With pass by reference, the argument object is modified even though it may not returned by the function. Pass by reference and pass by value are demonstrated below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var object = {
    'foo': 'bar'
},
num = 1;

// Passed by reference
;!function(obj) {
    obj.foo = 'baz';
}(object);

// => Object {foo: "baz"}
console.log(object);

// Passed by value;
;!function(num) {
    num = 2;
}(num);

// => 1
console.log(num);

Function Types

Now that we have a better understanding of blocks, and arguments lets dive deeper into Function Declaration and Function Expression, the two types of functions used in JavaScript. To the casual reader the two appear very similar:

1
2
3
4
5
6
7
8
9
// Function Declaration
function isLie(cake){
    return cake === true;
}

// Function Expression
var isLie = function(cake){
    return cake === true;
}

The only real difference between the two, is when they are evaluated. A function declaration can be accessed by the interpreter as it is being parsed. The function expression on the other hand is part of an assignment expression, which prevents JavaScript from evaluating it until the program has completed the assignment. This difference may seem minor, but implications are huge; consider the following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
// => Hi, I'm a function declaration!
declaration();

function declaration() {
    console.log("Hi, I'm a function declaration!");
}

// => Uncaught TypeError: undefined is not a function
expression();

var expression = function () {
    console.log("Hi, I'm a function expression!");
}

As you can see in the previous example the expression function threw an exception when it was invoked, but the declaration function executed just fine. This exception gets to the heart of the difference between declaration and expression functions. JavaScript knows about declaration function and can parse it before the program executes. Therefore, it doesn’t matter if the program invokes the function before it is defined. This is because behind the scenes JavaScript has hoisted the function to the top of the current scope. The function expression is not evaluated until it is assigned to a variable; therefore it is still undefined when invoked. This is why good code style is to define all variables at the top of the current scope. Had we done this then our script would visually match what JavaScript is doing during parsetime.

The concept to take away is that during parsetime JavaScript moves all function declarations to the top of the current scope. This is why it doesn’t matter where declarative functions appear in the script body.

To further explore the distinctions between declarations and expressions, consider the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
function sayHi() {
    console.log("hi");
}

var hi = function sayHi() {
    console.log("hello");
}

// => "hello"
hi();

// => 'hi'
sayHi();

Casually reading this code, one might assume that the declaration function would get clobbered because it function expression has an identical name. However, since the second function is part of an assignment expression it is given its own scope, and JavaScript treats them as seperate entities. To make things even more confusing look at this example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var sayHo

// => function
console.log(typeof (sayHey))

// => undefined
console.log(typeof (sayHo))

if (true) {
    function sayHey() {
        console.log("hey");
    }

    sayHo = function sayHo() {
        console.log("ho");
    }

} else {
    function sayHey() {
        console.log("no");
    }

    sayHo = function sayHo() {
        console.log("no");
    }

}

// => no
sayHey();

// => ho
sayHo();

In the previous example we saw that functions of the same name were considered different if one was an expression and the other was a declaration. In this example we are attempting to conditionally define the function based on how the program executes. Reading the script’s control flow you’d expect sayHey to return "hey" since the conditional statement evaluates true. Instead it returns "no", meaning the second version of the sayHey function clobbered the first. Even more confusing is that the sayHo function behaves the opposite way! Again, the difference comes down to parsetime versus runtime.

We already learned that when JavaScript parses the script it collects all of the function declarations and hoists them to the top of the current scope. When this happens it clobbers the first version of sayHey with the second because they exist in the same scope. This explains why it returns "no." We also know that function expressions are ignored by the parser until the assignment process completes. Assignment happens during runtime, which is also when the conditional statement is evaluated. That explains why the sayHo function was able to be conditionally defined. The key to remember here is that function declarations can not be conditionally defined. If you need conditional definition use a function expression. Furthermore, function declarations should NEVER be made inside a control flow statement, due to the different ways interpreters handle it.

Function Scopes

Unlike many other languages which are scoped to the block, JavaScript is scoped to the function. In Ruby (version 1.9.+) you can write this:

1
2
3
4
5
6
7
8
9
x = 20
10.times do |x|

  # => 0..9
  puts x
end

# => 20
puts x

What this demonstrates is that each block gets its own scope. Conversely, if we wrote similar code in JavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var x = 20;

// Functions have their own scope
;!function() {
    var x = "foo";

    // => "foo"
    console.log(x);
}();

// => 20
console.log(x);

for (x = 0; x < 10; x++) {

    // => 0..9
    console.log(x);
}

// => 10
console.log(x);

In JavaScript x is available inside the for loop, because as a control statement it belongs to the enclosing scope. This is not intuitive to many developers used to block level scope. JavaScript handles the need of block level scope at least partially through the use of closures which we’ll discuss later.

Debugging Functions

Before we wrap this topic up, lets briefly touch on debugging functions. In JavaScript naming a function expression is completely optional; so why do it? The answer is to aid the debugging process. Named function expressions have access to their name within the newly defined scope, but not in the enclosing scope. Without a name their anonymous nature can make them feel a bit like ghosts in the machine when it comes to debugging.

1
2
3
4
5
6
7
8
9
var namedFunction = function named() {

    // => function
    console.log(typeof(named));
}
namedFunction();

// => undefined
console.log(typeof(named));

Nameless function expressions will be displayed in the stack trace as "(anonymous function)" or something similar. Naming your function expression gives you clarity when trying to unwind an exception whose call stack may feel miles long.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * It is much harder to debug anonymous function expressions
 * Uncaught boom
 *    - (anonymous function)
 *    - window.onload
 */
;!function(){
    throw("boom");
}();

/*
 * Naming your function expressions give you a place to start looking when debuggin.
 * Uncaught boom
 *    - goBoom
 *    - window.onload
 */
;!function goBoom() {
    throw("boom")
}();
[1]http://kangax.github.com/nfe/

Pragmatic JavaScript Style

My goal is to make you a better programmer, and I am going to do this by teaching you about style. I am not talking about fashion, because I think most programmers would flunk that test; unless, comic-con couture is a thing. Instead we’ll talk about the importance of style, how it forms, how it spreads and when to kill it. Specifically, we’ll look at style as it applies to programming. Ultimately, once we have a context for evaluating style I will introduce you to elements of programmatic style which have served me well over the years as a professional software developer.

What Is Style?

Style is often used as a measurement of quality. When someone is described as having style or being stylish, it is almost universally meant as a complement. If someones’ style ever comes into question it is usually in comparison to someone else’s style. "My style’s the best and so I challenge you" screams 70’s era martial arts star.

Stylishness is a fresh approach, a unique perspective, an unexpected insight into an activity. The application of a style can become so prominent that it expands the activity itself; that house is built in a Frank Lloyd Wright style. What starts as a personal style in painting can become an art movement almost overnight. Style spreads like a virus, it is the original meme, a mind virus that changes the way you see the world forever. Style is often the conduit where new ideas pulsate.

How does style effect programmers? Well the good news about style for those algorithmically inclined is that, no matter how personal a style may seem, for it to exist it all, it must at some level be repeatable. Style must be codified into a series of steps, rules or combinations that can be followed, and then recognized by others. Therefore if style is a measurement of quality, and at the same time repeatable then it can be taught. Just ask Strunk and White.

William Strunk Jr. wrote "The Elements of Style" while he was a professor at Cornell. He began with 7 rules for the usage of language, and 11 principles of composition. His student E.B. White revised the book forty years later, by adding an additional 4 rules. The goal of the book was to give aspiring writers and grammarians a context from which to evaluate their own work.

According to White, Strunk was compelled to write the "little book" out of sympathy for those afflicted with reading the writer’s ill-composed dreck: "Will felt that the reader was in serious trouble most of the time, floundering in a swamp and that it was the duty of anyone attempting to write English to drain the swap quickly and get the reader up on dry ground, or at least throw a rope."

Over the years the book has remained wildly popular by those learning to write efficiently, and is affectionately referred to as "Strunk and White." That is not to say it has been universally loved or followed. Dorothy Parker is quoted in the New York Times as saying "If you have any young friends who aspire to become writers, the second-greatest favor you can do them is to present them with copies of ‘The Elements of Style.’ The first-greatest, of course, is to shoot them now, while they’re happy."

Many found the rules too restrictive, and opinionated. White said Strunk believed "…it was worse to be irresolute than to be wrong." Strunk’s assertions is that it takes passion to be stylish. You need to be able to draw boundaries, to allow this idea to flourish while forcing that one to die. Style is a sine wave attracting some and repelling others.

What is programmatic style?

As mentioned previously, Stunk and White wrote their book not only to empower and train writers, but to save readers from slogging through what was in their minds a textual tar pit. So too, good programmatic style services two audiences, the developer and the processor. That is to say that the code should be well-written, both syntactically, and technically. Below are qualities I consider essential in application of programmatic style:

Consistency - By repeatedly applying rules to the codebase we ensure consistency. Consistency, mitigates noise in the codebase, and brings the intent of the code into clearer focus. Put another way, if a developer is trying to piece together how to read your code, you have prevented them from understanding what it does. Consistency is concerned with how the code looks, e.g. naming conventions, use of whitespace, and method signatures; and how the code is written for example ensuring that all functions don’t return a string in one context and an integer in another.

Expressiveness - Code is by nature a symbolic language, where variability and abstractness is implicit. Therefore the developer must find a way to make the code meaningful to the reader. This can be archived though naming variables and methods precisely. When reviewing a class, method or variable the reader should understand the roles and responsibilities of the code by reading the code itself. If a method can only be understood by reading the comments above left by the writer it should be a clue that the code is not expressive.

Succinctness - Strive to do just enough. Good programming like good writing is about clarity of purpose, and not merely compactness. It should be about reducing the complexity of a method, not it’s usefulness.

Restraint - Style should never overpower the subject itself. At that point style becomes the subject it becomes a facile artifice, a dish ruined by too much spice. I am reminded of a minimalist chess set I saw in college every piece was either a white or black cube, and all pieces were the same size. It was aesthetically beautiful and simultaneously unplayable.

JavaScript Style Guide

This style guide was compiled by compiling, reviewing and considering choices I have made in my own work over the years, and coding practices of individuals, and development teams I admire in the JavaScript community. As such this style guide should be seen as an amalgamation of inputs and influences from the larger JavaScript community rather than the creative output of a singular individual. You can find a list of resources used in this guide in the additional resources section. This guide is broken into two sections: "Rules for Visual Clarity" and "Rules for Computational Effectiveness".

Caveats

Style guides are just that guides, they are meant to point you in the right direction, but they are at best mutable truth. Moreover, coding theory changes constantly and it is important not to lock yourself into a dogmatic approach to the application of these styles. As my professor Clyde Fowler told me in my studio drawing class, "you must think with your hands", and what he meant by that was you must think through doing, while maintaining the ability to get critical distance from your work.

Rules for Clarity - How others see code

Rules Of Thumb

  • Write Clearly And Expressively - When naming variables, functions, or organizing code remember you are writing for humans to read it not compilers.
  • Following Existing Conventions - If you share your code anywhere, work on a team, or are hired to write code, then you are not writing for yourself
  • Write in Only One Language - Where possible don’t use JavaScript as a surrogate for other languages. This means resisting the urge to write inline HTML, or CSS where possible.
  • Enforce A Uniform Column Width - Strive for consistent line lengths in source code. Long lines tire the eyes, and cause needless horizontal scrolling. An industry standard is 80 characters per line.

Document Formatting

  1. Naming Conventions

JavaScript is a terse language of brackets, and symbols and one of the only way to make your code expressive to humans is through the names you choose for variables, functions and classes among others. Remember when choosing a name it should describe the role and responsibilities of that object. Vague or obtuse names like doStuff is like telling the reader you figure it out, which often times they won’t.

  • Choose variables and functions with meaningful, expressive and descriptive names. Write for the reader not the compiler.
1
2
3
4
5
6
7
8
9
10
11
// Bad
var a = 1,
    aa = function(aaa) {
        return '' + aaa;
    };

// Good
var count = 1,
    toString = function(num) {
        return '' + num;
    };
  • Constants should always belong to a namespace, and be written in uppercase with spaces replaced with underscores
1
2
3
4
5
// Bad
MY_CONSTANT = 43;

// Good
com.humansized.MY_CONSTANT = 43;
  • Variables should be CamelCase
1
myVariableName
  • Classes should be PascalCase
1
MyAwesomeClass
  • Functions should be CamelCase
1
isLie(cake)
  • Namespaces should be CamelCase and use periods as a delimiter
1
com.site.namespace
  • Hungarian notation is not required but you can use it to convey they are objects constructed through or dependent on a library or framework
1
2
3
4
5
// JQuery infused variable
var $listItem = $("li:first");

// Angular.js uses the dollar sign to refer to angular-dependent variables
$scope, $watch, $filter
  1. Constants And Variables
  • Variables and constants definitions always go at the top of the scope
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Bad
function iterate() {
    var limit = 10;
    for (var x = 0; x < limit; x++) {
        console.log(x);
    }
}

// Good
function iterate() {
    var limit = 10,
        x = 0;

    for (x = 0; x < limit; x++) {
        console.log(x);
    }
}
  • Avoid polluting the global namespace by always declaring variables using var
1
2
3
4
5
// Bad
foo = 'bar';

// Good
var foo = 'bar';
  • Declare multiple variables using a single var declaration, but separate each variable with a newline
1
2
3
4
5
6
7
// Bad
var foo = "foo";
var note = makeNote('Huge Success');

// Good
var foo = "foo",
    note = makeNote('Huge Success');
  • Declare unassigned variables last. This allows the reader to know they are needed but have delayed initialization.
  • Do not assign variables inside a conditional statement, it often masks errors.
1
2
// Bad because it is easily misread as an equality test.
if (foo = bar) {...}
  • Do not clobber arguments with variables names.
1
2
3
4
5
6
7
8
9
10
11
// Bad
function addByOne(num) {
    var num = num + 1;
    return num;
}

// Good
function addByOne(num) {
    var newNum = num + 1;
    return newNum;
}
  1. Page Layout
  • Blank lines

    • Should always proceed the start of a comment

    • Should be used to separate logically related code

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      
      // Bad
      var = wheels;
      
      wheels.clean()
      
       car.apply(wheels);
      
      truck.drive();
      
      // Good
      var = wheels;
      wheels.clean()
       car.apply(wheels);
      
      truck.drive();
      
  • Commas

    • Remove trailing comments in object declarations. It will break some runtime environments.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      // Bad
      var foo = {
          bar: 'baz',
          foo: 'bar',
      }
      
      // Good
      var foo = {
          bar: 'baz',
          foo: 'bar'
      }
      
    • Don’t use comma first formatting, if you don’t know what that means keep it that way!

  • Semicolons

    • Even though JavaScript determines semicolons to be optional many compilers expect them, therefore it is better to use them.
    • Useful for clearly delineating the end of a logical statement
    • Do not add meaningless semicolons
  • Whitespace

    • Should be removed from the end of a line

    • Should be removed from a blank line

    • Should not mix spaces and tabs

    • Should appear after each comma in a function declaration

      1
      2
      3
      4
      5
      
      // Bad
      function findUser(foo,bar,baz)
      
      // Good
      function findUser(foo, bar, baz)
      
    • Should not appear inside empty functions or literals

      1
      2
      3
      
      doThis();
      var foo = {};
      var arr = [];
      
  • Brackets And Braces

    • Use only where the compiler calls for it or where it enhances readability

    • Brackets should appear on the line that requires them

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
      // Bad
      if (hidden)
      {
       ...
      }
      
      // Good
      if (hidden) {
      
      }
      
    • Add whitespace in front and between brackets to aid readability.

      1
      2
      3
      4
      5
      6
      7
      
      // Bad
      if (condition) goTo(10);
      
      // Good
      if (condition) {
          goTo(10);
      }
      
    • There are a couple of exception to the previous rule

      1
      2
      3
      4
      5
      6
      7
      8
      
      // No Whitespace needed when there is a single argument
      if (foo) ...
      
      // No whitespace when a parenthesis is used as a scope container
      ;(function () {...})
      
      // No white space when brackets are used as a function argument
      function sortThis([2,3,4,1])
      
  • Strings

    • String should be constructed using single quotes

      1
      2
      3
      4
      5
      
      // Bad
      var foo = "Bar";
      
      // Good
      var foo = 'Bar';
      
    • Strings longer than the pre-determined character line limit should be reconsidered, if required they should be concatenated

  • Functions

    • Method signatures must be consistent. If a function returns a variable in one context it should return a variable in all contexts
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    // Bad
    var findFoo(isFoo) {
        if ( isFoo === true ) {
            return true;
        }
    }
    
    // Good
    var findFoo(isFoo) {
        if ( isFoo === true ) {
            return true;
        }
        return false;
    }
    
    • While not a requirement, returning early from a function can make the intent more clear

      1
      2
      3
      4
      5
      6
      7
      
      // Good
      var findFoo(isFoo) {
          if ( isFoo === true ) {
              return true;
          }
          return false;
      }
      
  • Comments

    • Should never trail a statement

    • Comments should be used sparingly, overuse of comments should suggest to the developer that their code is not expressive enough.

    • Comments should aways be written as a complete thought.

    • Multiline comments should always use the multiline syntax

      1
      2
      3
      4
      5
      6
      7
      
      // Some really
      // bad multiline comment
      
      /**
       * A well-formed multiline comment
       * so there...
       */
      

Rules for Computational Effectiveness

Rules Of Thumb

  • Assume File Will Be Concatenated - Modern applications often munge source JavaScript into a streamline file for production. You should defensively program your scripts to protect from switches in operation context and scope corruption.
  • Keep your code browser agnostic - Keep your business logic free of browser specific code by abstracting them into interfaces. This will keep your code on a clean upgrade path as browser fall in and out of fashion.
  • Never Use eval() - Ever
  • Never Use with() - Ever
  • Keep Prototype Pristine - Never modify the prototype of a builtins like Array.prototype because it can silently break other’s code which expect standard behavior.
  1. Equality Comparisons And Conditional Evaluation
  • Use "===" instead of "==" use "!==" instead of "!=" this is because JavaScript is very loose when testing equality.

  • When just testing for truthiness you can coerce the values

    1
    2
    
    if (foo) {...}
    if (!foo) {...}
    
  • When testing for emptiness

    1
    
    if (!arr.length) { ... }
    
  • You must be explicit when testing for truth

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    // Bad because all of these will be coerced into true
    var zero = 0,
    empty = "",
    knull = null,
    notANumber = NaN,
    notDefined
    
    if (!zero || !empty || !knull || !notANumber || !notDefined ) ...
    
    // Bad
    var truth = "foo",
    alsoTrue = 1
    
    if (truth && alsoTrue) ...
    
    // Good
    if (foo === true) ...
    
  1. Constants and Variables
  • When deleting a variable set it to null instead calling #delete or setting it to undefined

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    // Bad because undefined means the variable is useful but as yet has no value
    this.unwanted = undefined;
    
    /**
     * Bad because calling delete is much slower than reassigning a value.
     * The only reason to use delete is if you want to remove the attribute from an objects list of keys.
     */
    delete this.unwanted;
    
    // Good
    this.unwanted = null;
    
  1. Functions
  • Function Expressions

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    // Anonymous Function
    var anon = function () {
        return true;
    }
    
    // Named Function
    var named = function named() {
        return true;
    };
    
    // Immediately-invoked function, hides its contents from the executing scope.
    ;(function main() {
        return true;
    })();
    
  • Anonymous functions are defined at parse-time, and therefore do not have their names hoisted to the top of the scope.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    // Bad - Runtime Error
    iGoBoom();
    
    var iGoBoom = function () {
        alert('boom');
    }
    
    // Good
    iGoBoom();
    function iGoBoom() {
        alert('boom');
    }
    
  • Do not use function declaration within block statements it is not part of ECMAScript; instead use a function expression.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    // Bad
    if (ball.is(round)) {
        function bounce(){
    
            // Statements Continue
        }
        return bounce()
    }
    
    // Good
    if (ball.is(round)) {
      var bounce = function () {
    
          // Statements Continue
      }
    }
    
  • Do not hide the native arguments object by using the same name in a function

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    // Bad
    var foo = function(arguments) {
        alert(arguments.join(' '));
    }
    
    // Good
    var foo = function(args) {
        alert(args.join(' '));
    }
    
  1. Strings
  • When concatenating a string use Array#join for performance reasons.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    // Bad
    var lorem = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in\
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in\
    culpa qui officia deserunt mollit anim id est laborum.';
    
    // Good
    var lorem = ['Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
    'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in',
    'reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in',
    'culpa qui officia deserunt mollit anim id est laborum.'].join('');
    
  1. Objects
  • Should use object literal vs new Object

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    // Bad
    var person = new Object();
    person.firstName = "John";
    person.lastName = "Doe";
    
    // Good
    var person = {
      firstName: "John",
      lastName: "Doe"
    }
    
  • Don’t overwrite reserved words as keys

    1
    2
    3
    4
    5
    
    // Bad
    var person = { class : "Person" };
    
    // Good
    var person = { klass : "Person" };
    
  1. Arrays
  • Should use literal syntax for creation

    1
    2
    3
    4
    5
    
    // Bad
    var arr = new Array();
    
    // Good
    var arr = [];
    
  1. Responsibility Delegation
  • Only write code that is the responsibility of the program. Keep your code free of view layer and template code. Use a template library like mustache.js instead

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    var view = {
        title: "Joe",
        calc: function () {
            return 2 + 4;
        }
    }, output;
    
    // Bad
    output = '<div><h5>' + title + '</h5><p>' + calc() + '</div>';
    
    // Good
    var output = Mustache.compilePartial('my-template', view);
    
  • Keep JavaScript out of the HTML

    1
    2
    3
    4
    5
    6
    
    // Bad
    <button onclick="doSomething()" id="something-btn">Click Here</button>
    
    // Good
    var element = document.getElementById("something-btn");
    element.addEventListener("click", doSomething, false);
    
  1. Operating Context And Scope
  • Where possible wrap your code inside self executing functions. This will insulate your code from pollution by others, and make it easier to abstract

    1
    2
    3
    4
    5
    
    // Good
    ;(function( window, document, undefined) {
    
      // My Awesome Library
    })(this, document);
    
  • Design for duration-agnostic execution of code. This will prevent your code from building up a backlog of requests that may no longer be relevant

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    // Bad because this might take longer than 100 milliseconds to complete.
    setInterval(function () {
      findFoo();
    }, 100);
    
    // Good this will only be called again once findFoo has completed.
    ;(function main() {
        findFoo();
        setTimeout(main, 100);
    })();
    
  • Only use this in object constructors, methods and creating closures

  • To prevent breaking community code declaring an operating context e.g. "use strict" should be wrapped inside a self-executing function for modules or inside a function itself when needed

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    // Bad
    var bar = findLooseyGoosey();
    
    "use strict";
    
    var foo = findStrictly();
    
    // Good
    var bar = findLooseyGoosey();
    
    ;(function () {
      "use strict";
      var foo = findStrictly();
    })();
    
  1. Coercion
  • Conversion over Coercion

    1
    2
    3
    4
    5
    6
    7
    
    var num = '1';
    
    // Bad implicit coercion
    num = +num;
    
    // Good expressive conversion
    num = Number(num);