Crockford's 'The Good Parts' : a short review

244 views
Skip to first unread message

John G Harris

unread,
Jul 11, 2009, 2:10:47 PM7/11/09
to

This is a short review of a book that some people like very much and
others dislike just as strongly.

Title : JavaScript : The Good Parts
Author : Douglas Crockford
Details : O'Reilly, 2008 (1st Ed), 153 pages, ISBN 978-0-596-51774-8.
Errata : <http://oreilly.com/catalog/9780596517748/errata/>

I'll start by describing the content of the book, then follow this with
some unenthusiastic comments.


Content

The preface says "This is not a book for beginners" and "This is not a
book for dummies".


Ch 1 says "The language described in this book is a proper subset of
ECMAScript." The subset consists of those parts he considers to be
'good'.


Ch 2 describes the language using Pascal-style syntax diagrams, but only
the 'good' parts. For instance, semicolons can't be omitted; names
(identifiers) can't start with underline; the statements inside if, for,
while, and do statements must be wrapped in curly brackets, with one
exception (else if).


Ch 3 describes objects and ways to access their contents. Object
literals are always used to create new objects.


Ch 4 describes functions and ways to use them, with subsections on
recursion, scope, closures, currying, and memoising (i.e. remembering
returned values for use in later calls). Throughout he emphasises that
functions are objects with methods that can be added to. Function
expressions are always used to create new functions, never declarations.

Ch 4 also describes exceptions.


Ch 5 describes three ways of implementing inheritance. Using
conventional constructors to do inheritance is deprecated as being ugly
and not really object-oriented.


Ch 6 describes arrays, with a complaint that they aren't designed for
speed, unlike other languages.


Ch 7 describes regular expressions in considerable, but not complete,
detail.


Ch 8 describes many of the methods available to Array, Function, Number,
Object, RegExp, and String objects.


Ch 9 discusses his coding style, much of which is built into the syntax
diagrams of Ch 2.


Ch 10 is a two-page essay on "beautiful features".


Appendix A describes the 'awful' parts of javascript and Appendix B
describes the 'bad' parts. These are the features of the language that
are not in the 'good' parts. For instance, optional semicolons are
declared to be awful and 'new' is declared to be bad.


Appendix C describes JSLint : a program that checks that javascript code
has been restricted to the 'good' parts and conforms to the style rules.
The errata contains a complaint that this appendix is already out of
date.


Appendix D repeats the syntax diagrams of chapters 2 and 7 in
alphabetical order and without any explanatory text.


Appendix E describes JSON (javascript object notation), a text format
for data interchange. Each data item is a javascript literal so making
it easy for javascript code to handle.

Appendix E includes a non-trivial example of javascript code in the form
of a recursive descent parser for JSON text.


Remarks

1 Some of the 'good' parts are simply his preferred coding style.
Nowhere does he hint that perhaps other people's preferences could just
possibly be equally right.


2 He doesn't mention there were earlier versions of javascript that
didn't have features such as apply and hasOwnProperty.


3 He says that a property's value cannot be 'undefined'. This is
untrue. (p20)


4 He thinks that typing
Thing.prototype.x = ... ;
is so ugly, and that doing
Thing.method('x', ... );
is so much nicer. Especially when ... is a function expression. (p33)


5 Closures are not explained very well. Specifically, he doesn't
explain the meaning of 'bound to the variable' and similar phrases.
(p37..39)


6 He gives an example of conventional inheritance that is badly
designed and badly implemented, then uses it as an excuse to say that
constructor-based inheritance is ugly and not really OO, hence not
'good'. (A base instance is used as a prototype object; the base
constructor's code is rewritten in the derived constructor.) (p47..49,
54)


7 He doesn't mention the Date object.


8 "I *always* use blocks with structured statements" (his emphasis). It
seems he doesn't understand the subtle difference between always and
nearly always (else if). (p95)


9 Making it legal to omit semicolons is said to be a way to cope with
faulty programs. He does not even hint that some very vocal people
strongly object to using semicolons in scripting languages. Also, that
Netscape's JavaScript reference manual seldom used them. Likewise for
'var'. (p102)


10 He sometimes forgets to type 'new' when creating a new object, so he
strongly recommends that the use of 'new' should be avoided as much as
possible. Examples of ways to do this appear throughout the book. (E.g
the 'beget' function (p22)). They all look nasty. (p114)


11 In case 'new' is used he has a style rule, built into JSLint, that
forbids constructors being called as ordinary functions. This means that
the base constructor's work cannot be re-used in derived constructors.
(p114, p123)


12 He believes that blocks, { ... }, are not statements. This is a
distressingly common urban myth that is untrue in Algol, Pascal, Simula,
C, C++, Java, C#, and ECMAScript. (p118)


13 He prefers code to be flashy and obscure rather than simple and
clear. For instance, in the parser example of Appendix E there are four
pages of function definitions that are separated by commas because they
are all part of one large var statement. (If you add a function, will
you remember to put in the preceding comma?) (p140..144)


Conclusions

Beginners should not read this book until they have gained more
experience, preferably including another programming language.

Non-beginners : read the book if you must but don't believe any part of
it without a lot of careful thought.


--
John Harris

Peter Michaux

unread,
Jul 11, 2009, 6:47:48 PM7/11/09
to
On Jul 11, 11:10 am, John G Harris <j...@nospam.demon.co.uk> wrote:

> 1  Some of the 'good' parts are simply his preferred coding style.
> Nowhere does he hint that perhaps other people's preferences could just
> possibly be equally right.

Crockford's writing frequently comes off as arrogant. For example, his
*many* comments about JavaScript being "broken" are irksome at least.
(Perhaps those comments are not in the book.) I'll agree JavaScript
has problems. I think everyone would agree with that but the language
itself is not "broken" and his dislike of certain features doesn't
make it so. To write it is unequivocally "broken" is only
antagonistic. (Just for frame of reference, I think JavaScript is one
of the most screwed up derivatives of Scheme I've seen. So it isn't
like I'm out to protect the reputation of the language.)

There is another side to his confidence. Crockford, through his
apparent conviction that his thoughts are superior to others, was one
of the main people, if not the main person, who put derailed
ECMAScript 4. It seems to me that *was* the right move and not many
people would have stood up against the momentum of ES4 so fearlessly.


> Non-beginners : read the book if you must but don't believe any part of
> it without a lot of careful thought.

I think this is the point of reading Crockford's book. It provokes
thought which is good. Crockford is a thoughtful programmer and has
spent a lot of time thinking about the language. Having a window to
look into another experienced programmer's mind is one of the most
valuable ways to reflect on one's own thoughts.

Peter

Peter Michaux

unread,
Jul 11, 2009, 6:48:44 PM7/11/09
to
On Jul 11, 11:10 am, John G Harris <j...@nospam.demon.co.uk> wrote:
> This is a short review of a book that some people like very much and
> others dislike just as strongly.
>
> Title   : JavaScript : The Good Parts
> Author  : Douglas Crockford
> Details : O'Reilly, 2008 (1st Ed), 153 pages, ISBN 978-0-596-51774-8.
> Errata  : <http://oreilly.com/catalog/9780596517748/errata/>
>
> I'll start by describing the content of the book, then follow this with
> some unenthusiastic comments.

<FAQENTRY>

Peter

David Mark

unread,
Jul 12, 2009, 1:53:40 AM7/12/09
to

Yes, should be warned against. Very unfortunate title.

Paul E. Schoen

unread,
Jul 12, 2009, 2:34:20 AM7/12/09
to

"John G Harris" <jo...@nospam.demon.co.uk> wrote in message
news:8E0bVrIn...@J.A830F0FF37FB96852AD08924D9443D28E23ED5CD...

>
> This is a short review of a book that some people like very much and
> others dislike just as strongly.
>
> Title : JavaScript : The Good Parts
> Author : Douglas Crockford
> Details : O'Reilly, 2008 (1st Ed), 153 pages, ISBN 978-0-596-51774-8.
> Errata : <http://oreilly.com/catalog/9780596517748/errata/>
>
[snip]

> Conclusions
>
> Beginners should not read this book until they have gained more
> experience, preferably including another programming language.
>
> Non-beginners : read the book if you must but don't believe any part of
> it without a lot of careful thought.

As a noob with experience in C and Borland Delphi Pascal I agree with some
of the observations of flaws or annoyances in the language, but I think it
is at least as good as VBscript. Unfortunately the WSH allows more to be
done in VBscript than Jscript or JavaScript. And the implementation of
JavaScript in Nitro PDF documents is quirky, but that is what is supplied
and I have to work with that.

At least now I have a better understanding of what can and can't be done in
JavaScript and the limitations of the objects that are available in various
contexts. I have been able to use it to write a simple JS which makes an
HTML index.htm file I can use for directory listings on my website. The
code is available at:
http://mysite.verizon.net/peschoen/Muttley/!MakeIndexHtm.js.
The files in that directory are mostly pictures of my dog Muttley.

Paul


Dr J R Stockton

unread,
Jul 12, 2009, 12:56:37 PM7/12/09
to
In comp.lang.javascript message <8E0bVrIn...@J.A830F0FF37FB96852AD0
8924D9443D28E23ED5CD>, Sat, 11 Jul 2009 19:10:47, John G Harris
<jo...@nospam.demon.co.uk> posted:

>7 He doesn't mention the Date object.

Reasonable. It is not a good part.

Errors include
* getYear -> 0-99
* 20th-centade bias
* months misnumbered
* separate routines for LCT & UTC
* undefined strings
* bad input strings
* no real ISO support
* inherited, rather than well-chosen, zero
* neither it nor Last-Modified is used for document.lastModified

Book Reviews are at least one of :
* unsupported conclusions
* too brief to be useful
* too long for the FAQ

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Proper <= 4-line sig. separator as above, a line exactly "-- " (SonOfRFC1036)
Do not Mail News to me. Before a reply, quote with ">" or "> " (SonOfRFC1036)

John G Harris

unread,
Jul 13, 2009, 9:38:23 AM7/13/09
to
On Sun, 12 Jul 2009 at 17:56:37, in comp.lang.javascript, Dr J R
Stockton wrote:
>In comp.lang.javascript message <8E0bVrIn...@J.A830F0FF37FB96852AD0
>8924D9443D28E23ED5CD>, Sat, 11 Jul 2009 19:10:47, John G Harris
><jo...@nospam.demon.co.uk> posted:
>
>>7 He doesn't mention the Date object.
>
>Reasonable. It is not a good part.

He thinks Boolean, Number, and String objects are completely
unnecessary, but that doesn't stop him mentioning them in the 'bad
parts' appendix. It's more likely that dates don't interest GUI
developers.

>Errors include
> * getYear -> 0-99
> * 20th-centade bias
> * months misnumbered
> * separate routines for LCT & UTC
> * undefined strings
> * bad input strings
> * no real ISO support

Very true.

> * inherited, rather than well-chosen, zero

The zero point is an internal matter that can be chosen arbitrarily. It
could have been the zero point of Modified Julian Day numbers, or of
Julian Day numbers. As it is, the zero point is late enough that it can
be linked to the present by national atomic time standards.

> * neither it nor Last-Modified is used for document.lastModified

You can't blame Date objects for the way lastModified is calculated or
presented.

>Book Reviews are at least one of :
> * unsupported conclusions
> * too brief to be useful
> * too long for the FAQ

I predicted you would say something silly.

John
--
John Harris

Jonathan Fine

unread,
Jul 13, 2009, 11:40:00 AM7/13/09
to
John G Harris wrote:

> He thinks Boolean, Number, and String objects are completely
> unnecessary, but that doesn't stop him mentioning them in the 'bad
> parts' appendix.

Sorry, I don't see your logic here. Cockcroft's book is mainly about
the good parts, and it has a bad parts appendix. He thinks String is a
bad part, and mentions it there.

I agree that String is a bad part. Consider this function:
var gotcha = function(obj){
obj.x = 1;
return obj.x === undefined;
};

Now solve, for x, the equation:
gotcha(x) === true;

Any such x is a good candidate for being a bad part.

--
Jonathan

Matt Kruse

unread,
Jul 13, 2009, 12:05:14 PM7/13/09
to
On Jul 11, 1:10 pm, John G Harris <j...@nospam.demon.co.uk> wrote:
> 1  Some of the 'good' parts are simply his preferred coding style.
> Nowhere does he hint that perhaps other people's preferences could just
> possibly be equally right.

Your review is great, thank you. But I'd like to say one comment about
this criticism.

I think it is helpful and necessary for those with experience and
knowledge in an area to separate out the good from the bad, and do so
in a biased manner. A "survey" of a language, or broad overview, is
helpful in some cases, but it's generally not what book-readers want,
and is most useful for academic purposes. What people (book buyers/
readers) want most is for someone who has gone through all that work
themselves, and can "short-circuit" the learning process by just
teaching the good stuff. In effect, "Don't teach me everything, just
teach me what I need to know!"

It can be difficult for anyone learning a language (especially js,
given its history, its many poor implementations, and the many
misconceptions about it) to sort through all the mess to figure out
what they should and shouldn't do. I am thankful that someone like
Crockford is able to say "listen, rather than show you everything in
js just so you have a full understanding of the language, I'm going to
cut out the stuff that you'll be better off not using to begin with,
and focus from the beginning on doing things in a way that will give
you less trouble."

Even though he puts forth his own personal preferences, I say that's a
_good_ thing. It is certainly not perfect, and you or anyone else is
welcome to write a book about your preferred approach also. But, being
someone very knowledgeable about the language, I would trust that he
would get it mostly right. Or at least right enough to not throw
someone completely off-base. You have some complaints about minor
things, but they are nothing compared to the severe errors pointed out
in a book by John Resig, for example! If someone new to js is looking
for advice, and a path to follow, surely he would be better off having
read a book like this than one of the many others that are far worse.

And then, once a person has adopted good habits (even if they are not
exactly as you would recommend) they will be in a better position to
decide on their own if they would like to tweak them later. At least
they started on solid ground. That's a lot better than starting in a
sea of confusing, conflicting information about js and trying to
figure out who knows what they are talking about and what bits are
important.

Matt Kruse

Jorge

unread,
Jul 13, 2009, 12:12:51 PM7/13/09
to

Well said. I couldn't agree any more. Thanks for posting that.

--
Jorge.

John G Harris

unread,
Jul 13, 2009, 2:54:53 PM7/13/09
to
On Mon, 13 Jul 2009 at 09:05:14, in comp.lang.javascript, Matt Kruse
wrote:

<snip>


>Even though he puts forth his own personal preferences, I say that's a
>_good_ thing. It is certainly not perfect, and you or anyone else is
>welcome to write a book about your preferred approach also. But, being
>someone very knowledgeable about the language, I would trust that he
>would get it mostly right. Or at least right enough to not throw
>someone completely off-base.

<snip>

I think that teaching people to use base instances as prototype objects
is unforgivable, especially when you're described by O'Reilly as the
world's foremost living authority on JavaScript.

Stroustrup describing C++ managed to show good examples without being a
dogmatic bigot.

John
--
John Harris

John G Harris

unread,
Jul 13, 2009, 2:56:20 PM7/13/09
to
On Mon, 13 Jul 2009 at 09:12:51, in comp.lang.javascript, Jorge wrote:

<snip>


>Well said. I couldn't agree any more. Thanks for posting that.

I predicted you would have something to say as well.

John
--
John Harris

John G Harris

unread,
Jul 13, 2009, 3:05:06 PM7/13/09
to
On Mon, 13 Jul 2009 at 16:40:00, in comp.lang.javascript, Jonathan Fine
wrote:

>John G Harris wrote:
>
>> He thinks Boolean, Number, and String objects are completely
>> unnecessary, but that doesn't stop him mentioning them in the 'bad
>> parts' appendix.
>
>Sorry, I don't see your logic here. Cockcroft's book is mainly about
>the good parts, and it has a bad parts appendix. He thinks String is a
>bad part, and mentions it there.
<snip>

Exactly. But my point is that he doesn't mention Date anywhere even
though he mentions other things he considers to be useless.

John
--
John Harris

Jorge

unread,
Jul 13, 2009, 5:06:52 PM7/13/09
to

Of course... :-)

--
Jorge.

Dr J R Stockton

unread,
Jul 13, 2009, 6:38:54 PM7/13/09
to
In comp.lang.javascript message <nt0C6dFP...@J.A830F0FF37FB96852AD0
8924D9443D28E23ED5CD>, Mon, 13 Jul 2009 14:38:23, John G Harris

<jo...@nospam.demon.co.uk> posted:
>On Sun, 12 Jul 2009 at 17:56:37, in comp.lang.javascript, Dr J R
>Stockton wrote:
>>In comp.lang.javascript message <8E0bVrIn...@J.A830F0FF37FB96852AD0
>>8924D9443D28E23ED5CD>, Sat, 11 Jul 2009 19:10:47, John G Harris
>><jo...@nospam.demon.co.uk> posted:
>>
>>>7 He doesn't mention the Date object.
>>
>>Reasonable. It is not a good part.

>> * inherited, rather than well-chosen, zero
>
>The zero point is an internal matter that can be chosen arbitrarily. It
>could have been the zero point of Modified Julian Day numbers, or of
>Julian Day numbers. As it is, the zero point is late enough that it can
>be linked to the present by national atomic time standards.

Since JavaScript actually uses, proleptically where necessary, the
Gregorian Calendar with "GMT" type days (i.e. no Leap Seconds), and only
current-day Summer time rules, it has in practice no connection with a
theoretical scale of SI seconds. The only link is that new Date()
should correspond with the computer clock which should correspond with
civil time, plus the knowledge that "GMT"-type time is indeed a (mean)
solar time therefore tracking calendar date. Chronological standards
are really not relevant.

Another error is the use, in method names and documentation, of "UTC".
"UT" would have been up-to-date and accurate (but too like "UTC").
"GMT" should have been used.

--
(c) John Stockton, nr London, UK. ?@merlyn.demon.co.uk Turnpike v6.05.
Web <URL:http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc : <URL:http://www.merlyn.demon.co.uk/programs/> - see 00index.htm
Dates - miscdate.htm estrdate.htm js-dates.htm pas-time.htm critdate.htm etc.

Peter Michaux

unread,
Jul 14, 2009, 12:38:29 AM7/14/09
to
On Jul 13, 11:54 am, John G Harris <j...@nospam.demon.co.uk> wrote:
> On Mon, 13 Jul 2009 at 09:05:14, in comp.lang.javascript, Matt Kruse
> wrote:
>
>   <snip>>Even though he puts forth his own personal preferences, I say that's a
> >_good_ thing. It is certainly not perfect, and you or anyone else is
> >welcome to write a book about your preferred approach also. But, being
> >someone very knowledgeable about the language, I would trust that he
> >would get it mostly right. Or at least right enough to not throw
> >someone completely off-base.
>
>   <snip>
>
> I think that teaching people to use base instances as prototype objects
> is unforgivable,

Why? That is how prototype-based languages work.

Peter

David Mark

unread,
Jul 14, 2009, 12:50:04 AM7/14/09
to

There seems to be a breakdown in communication here. Certainly
ECMAScript implementations do not work this way. Prototype objects
are not *instances* of anything (emphasis indicates the word doesn't
even belong in a discussion of these languages.)

John G Harris

unread,
Jul 14, 2009, 10:08:30 AM7/14/09
to
On Mon, 13 Jul 2009 at 16:40:00, in comp.lang.javascript, Jonathan Fine
wrote:

<snip>


>I agree that String is a bad part. Consider this function:
> var gotcha = function(obj){
> obj.x = 1;
> return obj.x === undefined;
> };
>
>Now solve, for x, the equation:
> gotcha(x) === true;

The brief answer is any primitive value, e.g true, 25.3, "Hi". The
longer answer goes as follows.

What does
obj = 25.3;
obj.x = 1;
actually mean? According to Crockford, numbers have methods but this is
another urban myth. Primitive values don't have anything to hang
properties onto. What happens is that the statement is first translated
into
( new Number(obj) ).x = 1;
Now we have an object on the left and it is meaningful to add an 'x'
property to it.

What about
return obj.x === undefined;
then? This is first translated into
return ( new Number(obj) ).x === undefined;
as before and then executed. The value returned is 'true' because the
new number is a different Number object. The first Number object was
thrown away because it wasn't assigned to anything. The second Number
object doesn't have an 'x' property.

The Boolean, Number, and String constructors aren't much use to
programmers but they made it easy for the language to behave as though
primitive values have methods.

John
--
John Harris

Thomas 'PointedEars' Lahn

unread,
Jul 14, 2009, 3:27:21 PM7/14/09
to

I do not know what "base instance" is supposed to mean. However, Google
knows I thought so some time ago, and it turned out that the ECMAScript
Specification disagrees with me. "Instance" might not be the best term as
it is confusing with respect to class-based OOP, but it is a term used
frequently in the Specification. So it is only only reasonable to adopt it
where it fits, as well as Specification-based terms like "global object",
"scope chain", and "activation object" have been adopted in discussions here.

As discussed before, the proposed concise surrogate term for "Foo instance",
"Foo object", is only a little bit less confusing as it can still refer both
to an object constructed with the object referred to by `Foo', and to the
constructor itself. With respect to DOM APIs and other multi-level
inheritance hierarchies, there are even three meanings attached to it, the
third being "Foo.prototype is in the prototype chain of said object".


PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm>

David Mark

unread,
Jul 14, 2009, 3:35:02 PM7/14/09
to

Yes, there is no doubt that new String, new Number, etc. are "bad
parts." They are how you come to see string tests that look like
this:

typeof xyz == 'string' || xyz instanceof String

I've heard that jQuery uses these functions as constructors because
Caja "requires" it. Sounds like their typical voodoo to me.

David Mark

unread,
Jul 14, 2009, 3:41:35 PM7/14/09
to
On Jul 14, 3:27 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:

[snip]

Fair enough. Consider the right-hand an "instance."

X.prototype = new Y();

We know that's not right by itself. I think what confuses people is
that the same line can appear in the right answer that clones an
existing prototype object, rather than setting the new prototype to a
"base instance", which would include properties assigned in the "base
constructor."

John G Harris

unread,
Jul 15, 2009, 3:38:43 PM7/15/09
to
On Tue, 14 Jul 2009 at 21:27:21, in comp.lang.javascript, Thomas
'PointedEars' Lahn wrote:
>David Mark wrote:

<snip>


>> There seems to be a breakdown in communication here. Certainly
>> ECMAScript implementations do not work this way. Prototype objects
>> are not *instances* of anything (emphasis indicates the word doesn't
>> even belong in a discussion of these languages.)
>
>I do not know what "base instance" is supposed to mean. However, Google
>knows I thought so some time ago, and it turned out that the ECMAScript
>Specification disagrees with me. "Instance" might not be the best term as
>it is confusing with respect to class-based OOP, but it is a term used
>frequently in the Specification. So it is only only reasonable to adopt it
>where it fits, as well as Specification-based terms like "global object",
>"scope chain", and "activation object" have been adopted in discussions here.
>
>As discussed before, the proposed concise surrogate term for "Foo instance",
>"Foo object", is only a little bit less confusing as it can still refer both
>to an object constructed with the object referred to by `Foo', and to the
>constructor itself. With respect to DOM APIs and other multi-level
>inheritance hierarchies, there are even three meanings attached to it, the
>third being "Foo.prototype is in the prototype chain of said object".

Instance is too useful a word to throw away. Take any lump of code that
creates objects that have a lot in common with each other. It's
reasonable to say that each object is an instance of the objects that
can be created by that lump of code. It's in javascript's nature for
there to be several ways to organise such lumps of code, so instance
shouldn't be restricted to one way of creating objects, unlike in
languages such as Java and C++.

As for 'base instance', suppose one lump of code creates objects that
have all the methods and data properties of objects produced by another
lump of code, plus some more. If you're thinking OO then obviously the
first lot of objects inherits a specification from the second lot of
objects, and the first lot are called derived, and the second lot are
called base. Obviously, an object belonging to the second lot is a base
instance.

It's not a good idea to use a base instance as the prototype object for
the derived instances. Instead, a separate lump of code should be used
to create the prototype. This lump of code presumably creates only one
object, but it is still reasonable to call the object an instance (of
the separate lump of code).

John
--
John Harris

Reply all
Reply to author
Forward
0 new messages