Tech Book Face Off: JavaScript: The Good Parts Vs. JavaScript Patterns

After learning a new language and getting comfortable with its syntax and feature set, it's a good practice to explore how to write well in that language. Each language has its own quirks, and writing well in a programming language means learning how to write in it idiomatically—how to structure statements, functions, and the entire program in a way that is most efficient for that language, and how other programmers expect things to be expressed in that language. I figured it was high time that I learn more idiomatic JavaScript, so I picked up a couple of books on the subject: JavaScript: The Good Parts by Douglas Crockford and JavaScript Patterns by Stoyan Stefanov. Both books are fairly slim, easy reads, but there's no need to read both. Let's see which one comes out on top.

JavaScript: The Good Parts front coverVS.JavaScript Patterns front cover

JavaScript: The Good Parts


Weighing in at a trim 100 pages for the main content of the book, JavaScript: The Good Parts is definitely a quick read. It's good, too, even though it may seem somewhat old for a book on a modern and constantly changing language. The content is still surprisingly relevant, and I think the author had the right approach. In Crockford's own words:
When I started thinking about this book, I wanted to take the subset idea further, to show how to take an existing programming language and make significant improvements to it by making no changes except to exclude the low-value features. We see a lot of feature-driven product design in which the cost of features is not properly accounted. Features can have a negative value to consumers because they make the products more difficult to understand and use. We are finding that people like products that just work. It turns out that designs that just work are much harder to produce than designs that assemble long lists of features.
With so many languages available today, each of them having huge lists of features, it's great to have a guide to a language that points out the parts of it that you should focus on and really understand how to use.
Most programming languages contain good parts and bad parts. I discovered that I could be a better programmer by using only the good parts and avoiding the bad parts. After all, how can you build something good out of bad parts?
That pretty much sums up the book. Crockford methodically goes through the JavaScript language, hitting all of the high points and periodically pointing out where things can go wrong. He describes the bad parts only as much as he needs to so that you know where you need not venture, because there be dragons. He runs through the grammar, objects, functions, inheritance, arrays and regular expressions. He finishes up with a chapter on the most useful methods in the standard library and a couple short chapters on style and what he considers the best features.

What are the best features? In a nutshell, they are the fact that functions are first class objects, prototypal inheritance, and the rich object literal syntax. The most controversial of these is probably prototypal inheritance because it is so different than anything most programmers have encountered. Crockford is encouraging:
JavaScript has a class-free object system in which objects inherit properties directly from other objects. This is really powerful, but it is unfamiliar to classically trained programmers. If you attempt to apply classical design patterns directly to JavaScript, you will be frustrated. But if you learn to work with JavaScript’s prototypal nature, your efforts will be rewarded.
I would definitely agree. Prototypal inheritance provides a great model for quite a few programming problems. You don't always need or want to construct an entire class to model something in code. Sometimes you want to build a simple object on the spot, possibly augment it with additional functionality later on, and then use that as a basis for other objects like it. It's a powerful paradigm that JavaScript has shown to be quite useful for both client side and server side programs.

JavaScript isn't all good parts, though, and Crockford does spend some time on the bad parts so that you know what to avoid. Probably the bad part that he spends the most time on is global variables, something that is a constant pitfall in JavaScript. He does a great job explaining how to circumvent this pitfall in all its incarnations. For example, here he is explaining how to make sure this is not bound to the global object:
When a function is invoked with this pattern, this is bound to the global object. This was a mistake in the design of the language. Had the language been designed correctly, when the inner function is invoked, this would still be bound to the this variable of the outer function. A consequence of this error is that a method cannot employ an inner function to help it do its work because the inner function does not share the method’s access to the object as its this is bound to the wrong value. Fortunately, there is an easy workaround. If the method defines a variable and assigns it the value of this, the inner function will have access to this through that variable. By convention, the name of that variable is that.
I didn't really understand the use of that when I would see it in code until I read this explanation. Now it makes total sense. He also touches on why you need to be careful of JavaScript's scoping rules, semicolon insertion, use of floating point numbers, and a dozen or so other things that will trip up the unwary programmer.

I love his treatment of the good and the bad parts of JavaScript, but the thing I like best is that he keeps things short and simple. It's quite possible to keep all of his advice in your head because he doesn't go on and on about the minutia of the language. Every page is packed with relevant, useful information, and because the book is so concise, it's easy to skim it periodically to refresh your memory. If you have to work with JavaScript in any capacity, I highly recommend this book to get the most out of the language with the least amount of pain.

JavaScript Patterns


Weighing in at twice the page count of JavaScript: The Good Parts, JavaScript Patterns came up a bit short for me. Going into this book, I was hoping to see two things. First, how the original GoF (Gang of Four) design patterns could be implemented in JavaScript, and second, learn some new patterns for a dynamic language with prototypal inheritance. Unfortunately, the GoF patterns weren't covered until the second-to-last chapter, and then only ten of the 24 patterns were covered. My second expectation was met somewhat better, but I was still left dissatisfied.

Not everything was bad, of course. Most of Chapter 2: Essentials was about laying out accepted style guidelines for writing code in JavaScript. These guidelines were quite similar to most other style guidelines I've read in other books. We seem to be reaching a point similar to the written word, where we have a generally accepted set of grammar and punctuation rules for writing code. I think this is a good thing. At least my concept of what good coding style looks like is consistent with a lot of other people in the industry, and if we can agree on the basics, it's easier to move to higher level programming issues and concepts.

Most of the patterns presented in this book, except for the last two chapters on GoF patterns and DOM/Browser patterns, were also in JavaScript: The Good Parts. Beyond those similarities, an unusual amount of space, three chapters in fact, was spent talking about classes and how to model them in JavaScript. JavaScript doesn't have any concept of classes, and the code is much cleaner and more effective if you stick to JavaScript's strengths, like prototypal inheritance and closures. It's a different paradigm than Object-Oriented Programming, but it's how JavaScript was designed. Why try to bolt on features to the language in a way that it wasn't originally designed for? You just end up writing a bunch of extra code to make the language do something it wasn't really meant to do. The author does allude to this fact and spends some time on JavaScript's unique features, but it does not seem that as much time is devoted to that as to trying to make JavaScript look like your standard object-oriented language.

For some patterns that were presented, it did not make sense to me why you would ever want to do such a thing. For instance, when Stefanov was describing how to expose private functions of an object as public methods, he exposes the same private function as two public methods with different names. Then he claims that if something happens to one of the public methods, the other one will still work as it did before. That's all well and good, but why would something happen to one of the public methods? That still seems bad. Then all other uses of that public method will have changed, even if the other public method maintains the same behavior. It doesn't seem terribly useful as a protection mechanism. It's really only useful as a way to create aliases for methods, which is a good thing in and of itself for making code more readable, but you really don't want to have anything happen to either name for the method.

Then in Chapter 6, where Stefanov describes different inheritance patterns, he continually uses a somewhat dubious example of a parent and child for the inheritance hierarchy. Inheritance is all about the 'is-a' relationship, meaning that the object that inherits behavior should be a derivative of what it inherits from, like a cat is a feline or a square is a quadrilateral. That doesn't work for a parent and a child because a child is not (necessarily) a parent. A child has a parent, but that's a different relationship where the child should have a member that is its parent. The child shouldn't inherit from its parent in code even if a real child does genetically. This misrepresentation made the sections on inheritance slightly confusing because the relationship was all wrong, and I had to keep reminding myself of what it should be.

Once he finally got to the GoF design patterns, it became quite apparent that most of these patterns are trivial to implement in a dynamic language that has closures and first class functions. Many of the original patterns were designed to solve issues that came up when writing programs in a more inflexible static language. Implementing iterators and decorators and proxies is easy when you can pass functions around and have them operate on arbitrary objects without having to deal with a complicated inheritance hierarchy to accomplish the same thing. That was quite a revelation for me.

Overall, JavaScript Patterns was probably not worth the effort, even though it was relatively short for a programming book. I didn't feel like I learned too much I didn't already know (barring the design patterns in a dynamic language stuff) and there were too many points where I found myself shaking my head at what the author was claiming. I'd pass over this book for something better.

Stick to the Good Parts


Of these two books, of course I recommend JavaScript: The Good Parts over JavaScript Patterns. The former has everything you need to take your JavaScript programming to the next level with no cruft whatsoever. Crockford does a great job of teaching how to write idiomatic JavaScript, and as far as I can tell, it's all still valid recommendations. JavaScript Patterns, on the other hand, covers the same useful material while adding a bit more that's not as useful, and it takes a few missteps along the way. I love that JavaScript: The Good Parts manages to give you everything you need in only 100 pages without any filler. That's the sign of a tightly focused, high quality learning experience. If you haven't read it yet, and you work with JavaScript, then you should go read it now. It shouldn't take long.

No comments:

Post a Comment