Notes on Teaching JavaScript
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.
March 3, 2010 at 12:00 AM
Awesome.
March 3, 2010 at 4:30 PM
Ian, could you describe the format of the lessons a bit - did you present a bit of theory each time and then you'd code together, or was it an almost exclusively hands-on approach, did you give any homework and were you following any book/site?
I'll probably have to do some internal JS training soon, so just curious about your experience with this and what would you change looking back (if anything). Cheers
March 3, 2010 at 5:11 PM
Artur: it varies. Usually we'll set the plan for next time at the end of each lesson. So far we've spent a lesson breaking down Resig's class inheritance solution, a lesson breaking down this jQuery inheritance pattern, a lesson spent setting up the nascent framework and writing a couple fundamental utility functions (namespace, etc.), and a few lessons going through existing code and refactoring/optimizing it.
We're far apart, so we use Skype and good old GNU screen to collaborate. Typically I (try to) let him drive and just sing out when I think of or notice something. When going through the inheritance stuff I tried to let him explain it to me. So I'd say that my goal has been to be more of a best practices reference and advisor than anything else, although if we get off on a tangent I try to guide us back to core ideas.
March 3, 2010 at 6:32 PM
Cool. That's basically how I learned myself as well.
Sounds like your designer friend isn't easily intimidated by code - inheritance, namespaces etc. :) My students will probably be a bit more timid :)
I'll probably end up reusing some low-level chunks from libraries esp. for the messy DOM stuff to keep focus on the big picture.
Anyway, best of luck with the teaching
March 4, 2010 at 8:11 AM
It was really great to read your reflections on this, Ian.
A few notes of my own:
* A lot of what I'm learning is how to debug and investigate things on my own. Some of the most interesting moments in our sessions are when a question or problem comes up that you don't already know the answer to and I get to see how you go about finding the answer.
* Some of the most valuable things I'm learning, from my perspective, are very practical. How to use vim, traditional organization structures for files and folders in a larger project, naming conventions, etc.
Artur: I'm very flattered that you think I'm not easily intimidated by code, but I am a bit intimidated by some of the concepts Ian and I've been working on. I find it frustrating that it's as much of a struggle as it is to really internalize high-order js concepts like scope management, inheritance, etc. My biggest suggestion would be not to underestimate how much learning and work has to go into internalizing larger concepts like those, and to have patience with your students.
March 4, 2010 at 2:40 PM
I feel your pain, Nate - I used to be a designer myself. In fact, I absolutely hated JavaScript :) Anyway, I'm sure with a bit of perseverance you'll be able to pull it off. Don't get discouraged by programmer jargon, just keep at it & there'll be a new star on the JS horizon in no time :)