James Crisp

Software dev, tech, mind hacks and the occasional personal bit

Review: JavaScript – The Good Parts by Douglas Crockford

“JavaScript: The Good Parts” was kindly lent to me by my friend and colleague Dave Cameron. It was a highly informative read, and a good length at just under 150 pages. The aim of the book is to define an elegant, recommended subset of JavaScript that allows you to do everything you need, and work around problems in the language. The book is aimed at people who already have a good grasp of programming in other languages.

I learnt quite a bit from the book. Here are a few of the most important parts that come to mind:

  • JavaScript has function scope, not block scope so it is best to declare variables at the top of functions.
  • It is important to put { on the same line as the block opening keyword (eg, function, if etc) rather than on the next line. Otherwise, you may run into problems with some JavaScript implementations auto-adding ; in the wrong place.
  • Using the === and !== operators are safer and better than the == and != operators as they do no coerce types.
  • The ‘new’ operator is a bad way to make new objects in JavaScript and should be avoided. Functions starting with a capital letter should always be called with the new operator by convention. Failing to do this will add all the functionality of the object you are trying to create to the global object (thanks to the this references)!
  • You can always pass any number of arguments to a function. Extra arguments are not bound to function parameters, missing arguments will be undefined. Inside the function all arguments are accessible using the ‘arguments’ variable which is an array-like object.
  • Lots of things are false. Eg, 0, NaN, empty string, null, and undefined.
  • hasOwnProperty(name) is great in for(property in object) loops to find members of your object rather inherited members.
  • Object.beget(someOtherObject) allows prototypal inheritance from someOtherObject.
  • JavaScript arrays are really just objects with numerical property names and the length property, so if you use a for in loop, you’ll get indices in random order.
  • It is a good idea to ‘namespace’ your code in a single global variable for your application to avoid conflicts with other libraries. Eg, myApp = {}; myApp.myVariable = 5;
  • If you don’t used var, a global variable is created.
  • Closures let you make information private and give you encapsulation.
  • Inner functions have access to the variables defined in an outer function.

Creating objects with private data:

var incrementer = function() {
  var value = 0;
  
  return {
    increment: function (inc) {
      value += typeof inc === 'number' ? inc : 1;
    },
    getValue: function() {
      return value;
    }
  };
};

var myIncrementer = incrementer();
 

Functional inheritance

var mammal = function(spec) {
  var that = {};
  
  that.getName = function() {
    return spec.name;
  };

  return that;
};

var myMammal = mammal({name: 'Fred'});
myMammal.getName() === 'Fred'

var cat = function(spec) {
  var that = mammal(spec);
  var super_getName = that.superior('getName');

  that.purr = function { /* new catty stuff */ };

  that.getName = function { 
    return super_getName() + ' the Cat!';
  };

  return that;
};

var myCat = cat({name: 'Kitty'});
myCat.getName() === 'Kitty the Cat!'

// Helpers

Object.method('superior', function(name) {
  var that = this, method = that[name];
  return function() { return method.apply(that, arguments); };
});

Function.prototype.method = function(name, func) {
  this.prototype[name] = func;
  return this;
};

There were a few things that I thought could be improved in the book. First of all, although the structure was adequate, it did lend itself to repetition. For example, scope is covered on p36 (in Functions section) and p102 (Awful parts), with very similar words. Secondly, I did not find the frequent syntax diagrams added much to the narrative.

Despite these small blemishes, I’m glad to have read Crockford’s book. I now understand much better which parts of JavaScript to use, and how to build good object oriented code in JavaScript.

Previous

XML: When to attribute and when to element?

Next

Wing Chun Notes

3 Comments

  1. JW

    Looking forward to this book! Most of the popular languages have gotten out of control with the size and associated learning curve. Most small things can be accomplished in a dozen lines of code. Chain them together (unix philosophy) and more scalable systems can be built.

    JW
    http://www.planetsdb.com

  2. CH

    What is the purpose of the `superior` method? AFAICT, since `myMammal.getName()` uses a closure-encapsulated variable (`spec`) instead of `this`, using another closure and `Function.prototype.apply` in `cat` to bind `this` to `getName` doesn’t actually do anything. If you write the same code with `var super_getName = that.getName`, it still produces the same results.

  3. @CH Thanks for the comment! The superior method was in Crockford’s examples. I don’t think it changes the functionality from just doing what you describe. The only difference that I can think of is that it adds a “super” style keyword to the closure based inheritance approach, like more OO focused languages have.

Comments are closed.

Powered by WordPress & Theme by Anders Norén