For the past few months, I've been tutoring a friend in JavaScript, and I've rediscovered some trite knowledge anew: there's no better way to improve in a subject than to teach it.



My friend and I come at programming JS from different directions: he's primarily a Web designer who uses jQuery to enhance pages that can stand on their own, while I'm a Python/Zope developer who's currently using ExtJS as the framework for a full-blown web application. I did a lot of thinking before our first session about how to approach the undertaking—should I teach to a framework, since that would yield the most immediate benefits? If so, which? Would I be able to explain best practices without going laboriously over never-again-used fundamentals of programming? Would our sessions even be worthwhile, since hundreds of tutorials are freely available?



Luckily my tutee was enthusiastic about learning from the bottom up, which was significantly easier for me, since that's how I learned myself. Despite the familiar trajectory, our sessions have been pretty educational for me, too, in part because they've highlighted the difficulties (and rewards) of teaching JavaScript, as distinct from those involved in learning it.



The first thing I realized was almost a tautology: different people approach JavaScript in different ways. The gap between designer and developer is quite large, and yet their disparate approaches are at once equally valid (grant me the possibly false dichotomy for just a minute). Other things being equal, designers want to add features and effects to their pages, to enhance the user experience. They think in CSS, and are primarily concerned with the manipulation of DOM elements. Developers, on the other hand, are used to complex APIs and constant refactoring, and are concerned with abstraction and (hopefully) readability.



A designer may be perfectly happy with a long jQuery chain that would cause a developer spiritual distress; a developer may confront a simple problem with an elegant but unnecessarily complex solution that only serves to frustrate the designer. Being primarily a developer myself, I had to realign a bit, to overcome my instinct to make things as useful as possible, instead of merely as useful as necessary. At the same time, I felt it was important to present the basic programming mores that guide the more technically minded scripter—jQuery chains be damned.



The second thing I realized: It's easy to learn JavaScript wrong. The overhead of fooling around with JavaScript is incredibly low. Everybody uses a browser every day, and as soon as you learn how to open the console, or install Firebug or Greasemonkey, you can have a visible effect on any of the hundreds of sites of whose shortcomings frequent use has made you achingly aware. At the same time, decent entry-level JavaScript information is oddly hard to come by. Most you find on the Web is outdated. Few tutorials adequately address cross-browser issues. And when you finally give up in frustration, there's always jQuery, which is incredibly easy both to use and to misuse.



Had jQuery been around when I needed the simple solutions, I might easily have managed to avoid the dirty low-level stuff to this day. Nothing, however, teaches you JavaScript quite so well as rolling your own cross-browser Ajax utilities, and so I studied the source code of Prototype and script.aculo.us and MochiKit, and now I'm a far better programmer than someone starting out today might be forced to become.



Since education was, in the instant case, the desired goal, I shied away from, say, teaching to jQuery (or even ExtJS or YUI, which are much closer in coding style to JavaScript per se), and guided our sessions as much as made sense towards a home-grown solution. Since my tutee is partially responsible for a large public site that needs only moderate, self-contained effects and widgets, but also would like his code to be reusable and readable by his many colleagues, he needed a little of the approach of both the designer and the developer. And so our ongoing project became to write a reusable, widget-focused library.



Creating a simple library turned out to be a fantastic learning exercise: it requires investigation of namespaces, presents plenty of scoping problems to overcome, and requires attention to consistency, organization and sane API design. It's immediately useful, so no worries about the student getting bored. A library is infinitely extensible, but can also contain the most trivial low-level utilities. Every library has its own style, and lets its coders be clever.



Most importantly, the creation of a library invites, and even insists upon, reiteration of what I find to be the most helpful guideline to keep in one's head while writing code: Assume a third party will one day attempt to extend everything you produce.



Personally, I've found the experience quite valuable, for one crucial reason: I'm not a designer. The interfaces and APIs I'd normally create would probably be most useful to somebody like me. Watching the thought processes of somebody in the thick of it by day as they design an API they'd like to use is enormously instructive.



Now, we're using jQuery as the basis for this library, because even though cross-browser issues are still unfortunately relevant, let's face it: frameworks are here, they aren't going anywhere, and they solve the problem without much effort, so it's not a paramount concern. Nonetheless, whenever we run into a problem, we write a solution from scratch before we use a jQuery shortcut (for example, we wrote a scope-setting decorator function similar to jQuery.proxy rather than just using proxy). When we've found a need to use something more complex, like class-like inheritance, we've studied many variations and written our own, and finally settled on a style that feels like jQuery but adds substantial value (no small feat, as the concept of class inheritance is nearly diametrically opposed to the jQuery ethos).



Probably nobody but my tutee's band of designers will ever use this library. But it's a great propadaeutic compromise, for both of us. I have an opportunity to share the best practices I've managed to distill from the pored-over source of other frameworks, and I get the chance to see things from the designer's point of view, rather than focusing on that of the implementer (me) or end user (actual end user).



If you can find a willing subject, I'd recommend the practice of teaching JavaScript as an excellent way to coalesce the lore into a science.