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:
// BAD EXAMPLE // Make a function that assigns event handler functions to an array of nodes the wrong way. // When you click on a node, an alert box is supposed to display the ordinal of the node. // But it always displays the number of nodes instead. var add_the_handlers = function (nodes) { var i; for (i = 0; i < nodes.length; i += 1) { nodes[i].onclick = function (e) { alert(i); } } }; // END BAD EXAMPLE // BETTER EXAMPLE // Make a function that assigns event handler functions to an array of nodes the right way. // When you click on a node, an alert box will display the ordinal of the node. var add_the_handlers = function (nodes) { var i; for (i = 0; i < nodes.length; i += 1) { nodes[i].onclick = function (i) { return function (e) { alert(i); }; }(i); } };
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.
o = new Object(); o.prop = 'exists'; o.hasOwnProperty('prop'); // returns true o.hasOwnProperty('toString'); // returns false o.hasOwnProperty('hasOwnProperty'); // returns false
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.
var date1 = new Date(); var milliseconds1 = date1.getTime(); var j=0; for (i=0; i < 1000000; i++) { j++; } var date2 = new Date(); var milliseconds2 = date2.getTime(); var difference = milliseconds2 - milliseconds1; alert(difference); var date1 = new Date(); var milliseconds1 = date1.getTime(); var j=0; for (i=0; i < 1000000; i++) { j = j + 1; } var date2 = new Date(); var milliseconds2 = date2.getTime(); var difference = milliseconds2 - milliseconds1; alert(difference);
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!