Javascript: The Good Parts - by Douglas Crockford
Posted on January 17th, 2017
This now traditional book about Javascript is the basis for a lot of what you’ll find in the most common javascript libraries out there before (and some after) EmacsScript 6. The book starts off defining why it is important to understand Javascript and take the best it has to offer to work with. As we move along, the author explains the grammar of the parts he considers to be the good parts of Javascript along with all keywords, literals (such as numbers and strings) and statements.
He moves on to explain how Javascript prototypal objects are different than the more common classical objects from Java and Smalltalk. An object in Javascript is simply a data structure that associates names to values. All objects have an associated prototype which is simply another object. The magic is that Javascript defines an implicit delegation between an object and it’s prototype. This means that if you try to access a given value on an object and it is not present, Javascript will try to access that value on the prototype of the original object. This happens recursively until you reach Object.prototype
which will return undefined
. Note that, a consequence of this is that you can augment any object in Javascript with functions by simply adding them to Object.prototype
. And herein lie the same dangers of open classes that Ruby has. If you find yourself with multiple libraries that increment Object.prototype
(or any other prototype for that matter) with similarly named functions, it is hard to know which implementation will apply to your program. This is one of the reasons why it is discouraged to increment Javascript prototypes that way unless they are your own.
Along those lines, Crockford explains that Javascript functions are also objects. But rather than having Object.prototype
as their parent prototype, they use Function.prototype
(which is itself linked to Object.prototype
). As a consequence of being an object, functions can be attributed to variables, to arrays, passed as arguments to other functions or returned. This quirckiness in functions is the use of this
. For functions embeded in an object, this
refers to the object being a way to access the object's properties. Unfortunatelly, for functions nested in those functions, this
does not bind to that same object. The workaround is to use a variable with another name (conventionally that
) to trap the value of this
in the embeded function. One of the many sources of issues in Javascript. A note from Crockford is that although Javascript functions can be recursive, there is not optimization regarding tail recursion so developers have to handle that manually.
Javascript also provides a few flow control keywords. return
is the most known one and simply exits the current function returning whichever value was provided. If return
is never invoked in a function, undefined
is returned. Unless the function was invoked with new
(we call those functions constructors) in which case, this
(the object created) is returned. throw
is another one and serves as an exception flow like Java or Ruby have. throw
takes an object that is expected to have name
and message
attributes and simply interrupts the execution of all functions in the stack until there is a catch
clause after a try
statement.
Scoping is another big source of mistakes since Javascript does not offer block scoping even if the syntax makes it look like it does. This means that scopes are bound to functions or their encasing objects. As a consequence, newer Javascript programs tend to have anonymous functions that execute immediately return objects with embeded functions as a way to ensure encapsulation of variables.
There is a whole section of the book about how to Javascript can handle inheritance and a more 'classical' (from classes not from classic) approach. History has shown that we're better off ignoring that all together when working in Javascript and rather stick with what Crockford calls "differencial inheritance". The idea is to simply create an object based on another (with a regular prototypal Object.create
) and then assign functions (or values) to the properties that the original object had.
Arrays are another one of those sources of issues in Javascript. Part of it is because an array is simply an object (that has Array.prototype
) which has properties that are numbered from 0 to the length of that array. Arrays get (from their prototype) a length
function which returns the last (numerical) property in the object plus one. There is no way to allocate a specific amount of memory for an Array in Javascript except for simply filling it with the data you want.
Crockford goes on afterwards explaining regular expressions in Javascript. They're mostly similar do perl's regular expressions and defined with /
s. There are capturing and non-capturing group as well as positive and negative lookahead. Regular expressions accept 3 modifiers (after the expression itself) that are g
for global (for multiple matches), i
for [case] insensitive, m
for multiline. If a regular expression is dynamic (and not hard-coded), one can use the RegExp
constructor to build the expression dynamically.
Chapter 8 handles methods which is simply a description of the functions associated to multiple prototypes that Crockford considers useful. The examples and explanations are sometimes still better than oficial documentation so take a look if you're curious but no need to read everything in detail. Chapter 9 approaches style and essentially how to format Javascript code. By now, most editors already handle this for you and linters are available to inspect and verify your code. Skip this chapter and use a linter and you'll be fine. Finally Chapter 10 summarizes what Crockford identifies as a subset of Javascript (mostly described in the book) that make it beautiful (in his opinion). If you're only reading one chapter, read this one and refer to the others to consult specific information.
The book ends with a few appendixes. The first one (A - the awful parts) is great. It pretty much summarizes the most common mistakes or problems encountered in Javascript programs around. Read it. It's worth it and it'll show you why some of the weird behaviors in Javascript are there. The second one (B - the bad parts) is still very interesting but reveals slightly more obvious issues or mistakes. The third one (C - JSLint) describes the work Crockford put together for the first Javascript linter around. By now, it is not that useful anymore. The fourth one (D - Syntax diagrams) shows diagrams that describe how to write/parse the language. Not that useful unless you want to play around and write weird Javascript. Finally, the last one describes JSON or Javascript Object Notation which, by now, if you don't know about, you probably should read before even starting this book. Crockford also provides an implementation of a JSON parser in Javascript. Interesting even if no longer very useful as there are so many out there.
Overall, the book is still relevant if you're anywhere near Javascript (which is anywhere near HTML) and quite short to deserve the full read. If you are in a super hurry, get Chapter 10 along with Appendix A and B if you already know some Javascript. Use the rest of the book as references. If you know nothing, just read the whole book. You'll be better off. I really liked it and it was definitively worth my time.