Posted on 29-04-2008
Filed Under (Book Review) by Cody

I was really excited when I saw O'Reilly was publishing a Javascript book by Douglas Crockford.

Crockford is one of the leading minds in Javascript, and I was fortunate enough to find his insights early in my Javascript learning days.

I read his take and implementation of Classical inheritance with Javascript a while back and remember thinking how nifty Javascript really could be.

I had the same reaction after reading Javascript: The Good Parts.

While most I already was familiar with most of the items covered in the book (closures), I still learned a great deal (always declare variables at the top) and was reminded of a bit more and encouraged to try some things I never have before (JSLint).

Knowledge of closures and how they work in Javascript separates mediocre Javascript development from solid to good Javascript development.

I nearly always have a test question about closures for interviewees.

Crockford does a better than adequate job explaining them, including a very common gotcha:

  1.  
  2. // BAD EXAMPLE
  3.  
  4. // Make a function that assigns event handler functions to an array
  5. of nodes the wrong way.
  6. // When you click on a node, an alert box is supposed to display the ordinal
  7. of the node.
  8. // But it always displays the number of nodes instead.
  9.  
  10. var add_the_handlers = function (nodes) {
  11. var i;
  12. for (i = 0; i < nodes.length; i += 1) {
  13. nodes[i].onclick = function (e) {
  14. alert(i);
  15. }
  16. }
  17. };
  18.  
  19. // END BAD EXAMPLE
  20.  
  21. // BETTER EXAMPLE
  22.  
  23. // Make a function that assigns event handler functions to an array of nodes
  24. the right way.
  25. // When you click on a node, an alert box will display the ordinal of the node.
  26.  
  27. var add_the_handlers = function (nodes) {
  28. var i;
  29. for (i = 0; i < nodes.length; i += 1) {
  30. nodes[i].onclick = function (i) {
  31. return function (e) {
  32. alert(i);
  33. };
  34. }(i);
  35. }
  36. };
  37.  

Harnessing the power of closures is the coolest thing about Javascript and really shows off what the language is good at.

Additionally, Crockford reminded me of hasOwnProperty. hasOwnProperty is a life saver when built in objects begin to get extended.

  1.  
  2. o = new Object();
  3. o.prop = 'exists';
  4. o.hasOwnProperty('prop'); // returns true
  5. o.hasOwnProperty('toString'); // returns false
  6. o.hasOwnProperty('hasOwnProperty'); // returns false
  7.  

There are a couple things I don't feel as strongly about.

Crockford rails on global variables, as most Javascript developers do. I used to be of this ilk but have backed of the vitriol lately.

Teams need to set down a convention for global variables. We use "g_". This avoids 99% of name collisions. We usually saw those when we'd create a global variable "var sport = 'nfl'" and then analytics script or ad script would set a variable "var sport = 'National Football League'".

Yes, these bugs are extremely difficult to track down sometimes, but I don't think namespacing everything is required as Crockford suggests.

I also don't understand why Crockford places unary operators (especially -- and ++) in the "Bad Parts" section.

He explains that it creates harder code to maintain. I don't necessarily agree with that assessment and I've always thought there was a significant performance benefit to "++".

I'm not generally a guy who does this, but the script below should show there is a benefit, but it's not significant for my purposes.

  1.  
  2. var date1 = new Date();
  3. var milliseconds1 = date1.getTime();
  4. var j=0;
  5. for (i=0; i < 1000000; i++)
  6. {
  7. j++;
  8. }
  9. var date2 = new Date();
  10. var milliseconds2 = date2.getTime();
  11.  
  12. var difference = milliseconds2 - milliseconds1;
  13. alert(difference);
  14.  
  15. var date1 = new Date();
  16. var milliseconds1 = date1.getTime();
  17. var j=0;
  18. for (i=0; i < 1000000; i++)
  19. {
  20. j = j + 1;
  21. }
  22. var date2 = new Date();
  23. var milliseconds2 = date2.getTime();
  24.  
  25. var difference = milliseconds2 - milliseconds1;
  26. alert(difference);
  27.  

So, I guess "++ vs i = i +1" is a preference things. I'll stick with "++".

However, I totally agree with Crockford's assessment of placing variables.

In most languages, it is generally best to declare variables at the site of first use. That turns out to be a bad practice in JavaScript because it does not have block scope. It is better to declare all variables at the top of each function.

That means removing "var i = 0" from the loop declaration.

At times, Crockford comes off as a bit preachy as he can at times, but I get the impression that's because he truly is passionate about this stuff.

Finally, the appendix includes a great section on using JSLint, which I have played with but never used in production setting. I think I'll try that now.

Overall, this book is great for a beginner. In fact if all Javascript newbies would read this, the Javascript realm would be a happier, smarter one. For the good to great, it's a fun one-to-two-hour read that can be illuminating and a good review.

Of all languages, I have the most experience with Javascript, and that knowledge really helped me with learning Ruby. There are a lot of the same principles.

Interestingly though, Rails has moved me from a Fat Client (where as much code and functionality as possible is written in Javascript) Javascript developer to a Thin Client guy.

This mostly is due to RJS, which pretty much necessitates two Ajax/Javascript patterns: On-Demand Javascript and HTML Message.

Oh, one last thing in the book that I flat out did not know. parseInt can take a radix parameter, so that parseInt("08", 10) produces 8. Amazing! That caused me a lot of headaches!

(1) Comment    Read More