Blog


50% Off Secrets of the JavaScript Ninja

I've been slowly working on a new JavaScript book that covers many of the specifics behind how and why JavaScript libraries are designed they way that they are - titled Secrets of the JavaScript Ninja. I'm still working on the book - I have four chapters left to write - and am hoping to have it completed this year.

Incidentally Manning Publishing is running a special (today only!) offering the ebook version of Secrets of the JavaScript Ninja for 50% off the normal price, if you use the coupon code pop0901. (Note: I've heard that it may also work for the ebook + paperback version of the book.)

A number of excerpts from the book can be found in the site archive. My Learning Advanced JavaScript interactive tutorial is also based upon the contents of the book.

Note: The book is not yet complete, nor has it gone through any proofreading or technical editing - there will be mistakes. Also, yes, I'm aware that the cover of the book has a samurai on it, not a ninja - I'm working with the publisher to rectify this.

I've also been asked if people should buy Pro JavaScript Techniques (my Apress book from 2006) or my upcoming one. I should note that the upcoming one is much more advanced than my previous one - covering much more complicated topics and more about cross-browser development. If you're looking for a good introductory book to JavaScript and the DOM I strongly recommend Nicholas Zakas' Professional JavaScript Developers book.

Tags: javascript, book, programming

Podcast #2, SXSW, Ninja Articles

Open Web Podcast #2

The second edition of the Open Web Podcast is now live. In this episode we brought on Brendan Eich and Arun Ranganathan (both of Mozilla) to discuss the recent changes that occurred in the ECMAScript 3.1/ECMAScript 4 processes that resulted in ECMAScript Harmony. This is a dense podcast - going just over an hour.

The podcast is available as an mp3, ogg, an RSS feed, and on iTunes.

Next week we're hoping to bring on some people from the Microsoft JScript team to discuss the recent changes and how they plan on implementing them in Internet Explorer. The topic isn't clear for the week after that, but we'll probably want to get back to discussing HTML 5 of the new Open Web Foundation.

Also, we now have a dedicated site for the podcast: openwebpodcast.com.

SXSW 2009

I've submitted two talks to South by Southwest 2009 - naturally both on JavaScript. If these talks interest you please feel free to vote on them appropriately. Last year there were a lot of complaints concerning the lack of technical talks - I hope to rectify that this year.

More Secrets of JavaScript Libraries

In a reprise from last year's popular panel - the JavaScript libraries authors are getting together again to impart their what they've learned from their experience in developing solid, world-class, JavaScript libraries. Covering everything from advanced aspects of the JavaScript language, to handling cross-browser issues, all the way up to packaging and distribution. A complete set of knowledge for a JavaScript developer.

I plan on having representatives from Dojo, Yahoo UI, and Prototype on the panel (will probably switch up the speakers from last year, just to keep things interesting).

Practical JavaScript Development

Modern JavaScript development can be quite harrowing. With a multitude of browsers to support and a bevy of design and performance considerations - only the best solutions will suffice. In this talk JavaScript developers will be given the best advice for improving the quality of your JavaScript code, writing reusable JavaScript code-bases, and tackling difficult cross-browser situations; providing you with an expert level of knowledge, immediately.

Secrets of the JavaScript Ninja Articles

Work continues on my upcoming book (about halfway done at this point - working on Chapter 10). But in the meantime some article extracts have been released on Ajaxian:

Enjoy! Note that these are only extracts of the larger chapters: Closures and Function Prototypes.

Tags: book, podcast, sxsw

JavaScript Ninja Jobs

JavaScript Jobs

After an outpouring of interest, in last week's post about JavaScript Jobs, I've gone about and set up a free site dedicated to JavaScript Jobs, which can be found here:

http://jobs.jsninja.com/

It's pretty basic, for now. I used the Open Source jobberBase software (which uses jQuery!) so it was pretty easy. All jobs go through a simple moderation process, so I hope that the signal-to-noise will be decent.

The important thing, however, is that it's completely free to both post and apply for jobs. I want to see more consulting/freelance/"quick hack" gigs - and those are the ones that can't afford a large fee (why pay $100 when the job will only cost $200?). At this point I'd much rather have a community build up around this than to profit off of it - so enjoy!

Here's an RSS feed that you can subscribe to, of all the jobs, as well:

Secrets of the JavaScript Ninja Book

You may notice the URL used for this job board - being located on jsninja.com. This is where my upcoming book will, eventually, be released. I'm placing this job board there because I want to start building a community of JavaScript hackers. One part of that is jobs and work (an other is community - such as a forum - and the rest is education - which I hope to seed with my book).

For now the Secrets of the JavaScript Ninja Book site is pretty much just a splash page - with an awesome ninja (drawn by my brother Steve - he's available for illustration work, contact me if interested). Expect lots more to come.

Tags: book, javascript, jobs

Simple JavaScript Inheritance

I've been doing a lot of work, lately, with JavaScript inheritance - namely for my work-in-progress JavaScript book - and in doing so have examined a number of different JavaScript classical-inheritance-simulating techniques. Out of all the ones that I've looked at I think my favorites were the implementations employed by base2 and Prototype.

I wanted to go about extracting the soul of these techniques into a simple, re-usable, form that could be easily understood and didn't have any dependencies. Additionally I wanted the result to be simple and highly usable. Here's an example of what you can do with it:

var Person = Class.extend({
  init: function(isDancing){
    this.dancing = isDancing;
  },
  dance: function(){
    return this.dancing;
  }
});

var Ninja = Person.extend({
  init: function(){
    this._super( false );
  },
  dance: function(){
    // Call the inherited version of dance()
    return this._super();
  },
  swingSword: function(){
    return true;
  }
});

var p = new Person(true);
p.dance(); // => true

var n = new Ninja();
n.dance(); // => false
n.swingSword(); // => true

// Should all be true
p instanceof Person && p instanceof Class &&
n instanceof Ninja && n instanceof Person && n instanceof Class

A couple things to note about this implementation:

  • Creating a constructor had to be simple (in this case simply providing an init method does the trick).
  • In order to create a new 'class' you must extend (sub-class) an existing class.
  • All of the 'classes' inherit from a single ancestor: Class. Therefore if you want to create a brand new class it must be a sub-class of Class.
  • And the most challenging one: Access to overridden methods had to be provided (with their context properly set). You can see this with the use of this._super(), above, calling the original init() and dance() methods of the Person super-class.

I'm pleased with the result: It helps to enforce the notion of 'classes' as a structure, maintains simple inheritance, and allows for the super method calling.

Simple Class Creation and Inheritance

And here's the implementation (reasonably sized and commented well) - clocking in at around 25 lines. Feedback is welcome and appreciated.

/* Simple JavaScript Inheritance
 * By John Resig http://ejohn.org/
 * MIT Licensed.
 */

// Inspired by base2 and Prototype
(function(){
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

  // The base Class implementation (does nothing)
  this.Class = function(){};
 
  // Create a new Class that inherits from this class
  Class.extend = function(prop) {
    var _super = this.prototype;
   
    // Instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    var prototype = new this();
    initializing = false;
   
    // Copy the properties over onto the new prototype
    for (var name in prop) {
      // Check if we're overwriting an existing function
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;
           
            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];
           
            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);       
            this._super = tmp;
           
            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }
   
    // The dummy class constructor
    function Class() {
      // All construction is actually done in the init method
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }
   
    // Populate our constructed prototype object
    Class.prototype = prototype;
   
    // Enforce the constructor to be what we expect
    Class.constructor = Class;

    // And make this class extendable
    Class.extend = arguments.callee;
   
    return Class;
  };
})();

In my opinion the two trickiest parts are the "initializing/don't call init" and "create _super method" portions. I want to cover those briefly so that you will have a good understanding of what's being achieved in this method.

Initialization

In order to simulate inheritance with a function prototype we use the traditional technique of creating an instance of the super-class function and assigning it to the prototype. Without using the above it would look something like this:

function Person(){}
function Ninja(){}
Ninja.prototype = new Person();
// Allows for instanceof to work:
(new Ninja()) instanceof Person

What's challenging about this, though, is that all we really want is the benefits of 'instanceof', not the whole cost of instantiating a Person object and running its constructor. To counteract this we have a variable in our code, initializing, that is set to true whenever we want to instantiate a class with the sole purpose of using it for a prototype.

Thus when it comes time to actually construct the function we make sure that we're not in an initialization mode and run the init method accordingly:

if ( !initializing )
  this.init.apply(this, arguments);

What's especially important about this is that the init method could be running all sorts of costly startup code (connecting to a server, creating DOM elements, who knows) so circumventing this ends up working quite well.

Super Method

When you're doing inheritance, creating a class that inherits functionality from a super-class, a frequent desire is the ability to access a method that you've overridden. The final result, in this particular implementation, is a new temporary method (._super) which is only accessible from within a sub-classes' method, referencing the super-classes' associated method.

For example, if you wanted to call a super-classes' constructor you could do that with this technique.

var Person = Class.extend({
  init: function(isDancing){
    this.dancing = isDancing;
  }
});

var Ninja = Person.extend({
  init: function(){
          this._super( false );
  }
});

var p = new Person(true);
p.dancing; // => true

var n = new Ninja();
n.dancing; // => false
 

Implementing this functionality is a multi-step process. To start, note the object literal that we're using to extend an existing class (such as the one being passed in to Person.extend) needs to be merged on to the base new Person instance (the construction of which was described previously). During this merge we do a simple check: Is the property that we're attempting merge a function and is what we're replacing also a function? If that's the case then we need to go about creating a way for our super method to work.

Note that we create an anonymous closure (which returns a function) that will encapsulate the new super-enhanced method. To start we need to be a good citizen and save a reference to the old this._super (disregarding if it actually exists) and restore it after we're done. This will help for the case where a variable with the same name already exists (don't want to accidentally blow it away).

Next we create the new _super method, which is just a reference to the method that exists on the super-class' prototype. Thankfully we don't have to make any additional changes, or re-scoping, here as the context of the function will be set automatically when it's a property of our object (this will refer to our instance as opposed to the super-class').

Finally we call our original method, it does its work (possibly making use of _super as well) after which we restore _super to its original state and return from the function.

Now there's a number of ways in which a similar result, to the above, could be achieved (I've seen implementations that have bound the super method to the method itself, accessible from arguments.callee) but I feel that this technique provides the best mix of usability and simplicity.

I'll be covering a lot more of the nitty-gritty behind the JavaScript prototype system in my completed work but I just wanted to get this Class implementation out there to get everyone trying it out and playing with it. I think there's a lot to be said for simplistic code (easier to learn, easier to extend, less to download) so I think this implementation is a good place to start and learn the fundamentals of JavaScript class construction and inheritance.


This topic will be discussed, in depth, in my work-in-progress book: Secrets of the JavaScript Ninja. To be released Fall 2008.

Tags: secrets, javascript, book

Search and Don't Replace

Earlier today a friend of mine, Marc Grabanski, pinged me with a question: What's the optimal way, in JavaScript, to convert a query string like "foo=1&foo=2&foo=3&blah=a&blah=b" into one that looks like this: "foo=1,2,3&blah=a,b". He had already come up with a solution of his own and was curious as to if it could be improved upon.

I pondered this for a moment and came up with a solution:

function compress(data){
    var q = {}, ret = "";
    data.replace(/([^=&]+)=([^&]*)/g, function(m, key, value){
        q[key] = (q[key] ? q[key] + "," : "") + value;
    });
    for ( var key in q )
        ret = (ret ? ret + "&" : "") + key + "=" + q[key];
    return ret;
}

Besides being 10 lines shorter than Mark's solution it also didn't require the use of any libraries (his required the use of jQuery). He was especially surprised at my result - and the replace technique that I used, in particular. I want to outline two quick tricks that I used that some may not be familiar with.

Array Joining Without an Array

One step to solving the above problem is to collect together the various values associated with a key - joining them with a ','. At first glance the obvious solution might be to construct an array for each key, push each of the values on, and then .join() the array results into a string. However all of this is both costly (the overhead of creating all these extra arrays) and verbose.

The alternative is one that I use twice in the program:

q[key] = (q[key] ? q[key] + "," : "") + value;

The key part is that we're concatenating the value onto the q[key] string adding in an extra "," if there's nothing in the string already: q[key] ? q[key] + "," : "". If no existing value is in the key we seed it with an empty string, otherwise we're simply merging on to the already-existing value along with the needed ",".

The end result is that we're only ever dealing with strings and string operations (instead of arrays) but achieving the result of joining a set of values without using an array.

Search and Replace Without Replacing

The second, and arguably more interesting, aspect is in using the JavaScript string replace function as a means of traversing a string for values, rather than as an actual search-and-replace mechanism. The trick is two-fold: Passing in a function as the replace value argument to the .replace() method and, instead of returning a value, simply utilizing it as a means of searching.

Let's examine this piece of code:

data.replace(/([^=&]+)=([^&]*)/g, function(m, key, value){});

The regular expression, itself, captures two things: A key in the query string and its associated value. This match is performed globally, locating all the key-value pairs within the query string.

The second argument to the replace method is a function. It's not uncommon to utilize this function-as-an-argument technique when attempting to replace matches with complex values (that is values that are dependent upon their associated matches). The function is called every time a new match occurs and it receives a variable number of arguments. The first argument is always the entire matched portion of the string and all remaining arguments are each of the (...) capturing blocks, in order. The return value of the function is injected back into the string as its replacement. In this example we don't return a value from the function therefore we end up injecting the serialized "undefined" value, repeatedly, back into the string.

We can see this behavior here:

"a b c".replace(/a/, function(){});
// => "undefined b c"
 

Now that we've collected all of our key values pairs (to be re-serialized back into a query string) the final step isn't really a step at all: We simply don't save the search-and-replaced data query string (which, most likely, looks something like "undefined&undefined&undefined").

In this manner we can use a string's replace method as our very-own string searching mechanism. The result is, not only, fast but also simple and effective. Another excellent tool in your JavaScript toolbox.


This topic will be discussed, in depth, in my work-in-progress book: Secrets of the JavaScript Ninja. To be released Fall 2008.

Tags: javascript, book, secrets

State of the Secrets

I've alluded to it a couple times now but it's probably important to state it definitively: I'm writing a new JavaScript book, to be published by Manning Publishing, called Secrets of the JavaScript Ninja. I published the rough Table of Contents previously and the contents of the book will be staying virtually the same (with a couple minor additions).

I wanted to take this opportunity to give a sort of progress update - letting you know what's happening. Not enough is said about the process of writing a book (especially technical ones) so I wanted to try and fill in some of the gaps.

Dec 28th: I first decided that I wanted to write a new JavaScript book around the end of last year. While it wasn't, explicitly, a new year's resolution - the timing was rather nice.

Dec 28-30th: I then set about collecting some information, trying to decide if the subject matter was worthwhile:

Jan 9th: I decided that I had enough information on hand to warrant a full book on the subject matter (namely advanced JavaScript techniques and cross-browser scripting). I started work on congealing this into a full outline/table of contents.

It was around this time that I started work on my first (non-introductory) chapter: Functions.

Jan 21st: It was around this time that I started talking with various publishers. Luckily I've been able to accrue a number of contacts in the technical publishing industry, over the past couple years, so I already had some starting points and good references. I also received a few contacts after my post on the profits of my previous book.

Jan 25th: I made the decision to go with Manning Publishing as the publisher of my book. I had the opportunity to have a number of long phone calls with Marjan (the head of Manning) and he had some fantastic ideas for the book and its direction. Hearing his ideas and excitement was a huge reason for me to go with them but in the end there were a number of reasons for choosing them:

  • They were very open to trying new techniques with the book - everything from how it was to be published, what the contents were, to even how the writing process worked.
  • When we originally started talks we were looking at the idea of having the book be similar, in style, to other books like Why's Poignant Guide to Ruby. We discussed this, at length, for quite some time. After a few weeks of mulling it over I decided that this wasn't the best course-of-action for this book. The mixture of complex material and narrative would not work well, I felt.
  • However, we agreed to include a heavier use of illustrations and figures to communicate difficult topics (such as timers or closures). We'll have to see how this works out, but that's the current plan.
  • The book will have a companion web site which will be open to those that have purchased a copy of the book. It will behave very similarly to the Django Book, in that you'll be able to comment on any portion of the text - becoming part of the editing and review process.
  • I'll be able to write the book using DocBook, which is a huge win over the old pass-Word-documents-around strategy that a lot of publishers use. Many technical publishers are getting better here - I definitely wouldn't want to go with one who didn't support this, or a similar, strategy.
  • They have a good level of distribution and their books are widely available in book stores.
  • We were able to negotiate a good level of compensation heavily tied to the sale of books, which made me happy.

Feb 3rd: Chapter 2 was completed and submitted on time. I now have an absolute schedule to work against. One chapter every 10 days until the end of August. It's pretty grueling (as is to be expected with book writing) but I'm optimistic. I started with Chapter 2 so that I could get a feel for how an actual chapter would be written (I dislike writing non-code chapters).

Feb. 17th: Chapter 3 (Closures) completed. I also released a portion of this chapter as a blog post: Partially Applying Functions in JavaScript. I fell behind with this chapter because I was traveling to Mountain View, for Mozilla work, during this period. I suspect that this will happen frequently throughout the summer as I'll be traveling a lot more.

Around this time I was assigned an editor for my book, Tom Cirtin. I look forward to working with him more - I'll certainly have plenty of opportunity for that.

Feb. 24th: Chapter 4 (Timers) completed. I'm virtually caught up at this point. However I have to jump back now and finish Chapter 1 (the introductory chapter) before moving on. I released one portion of this chapter as a blog post: How JavaScript Timers Work.

There's a lot that I'm doing differently from my first book and it's already making for a saner experience:

For starters this book is highly specialized, it picks one topic and covers it completely (there's a chapter on closures, on timers, on eval, on with - to name a few). I enjoy giving high-class treatment to obscure topics. Knowing that someone will be able to pick up this book and absolutely see something that they've (probably) never seen before makes for a very invigorating writing experience.

Another thing that I learned from my first book was that I really dislike long chapters. To counter this the book is broken up into 21 "small" 10-12 page chapters. I love it, it's the perfect chapter length, for me. I rarely find that I have more to say on a subject after about 4000 words (which is what 10-12 pages works out to be). With my old book I constantly felt like I had to flush out topics in order to meet page quotas, not so here. This causes me to become much more relaxed, knowing that whatever result I end up with it'll be an ideal length.

While I wouldn't call this book a 'cookbook' it's certainly not a traditional-style technical book. I'd say that it's something of a hybrid between the two. The chapters, thus far, have a structure like: In-depth explanation of topic, simple use of topic, specialized use of topic #1 through #3. For example in the chapter on Timers I dive in to how timers work, look at the minimum timer delays and reliability, explore computationally-expensive processing, build a centralized timer control, and finish up with a look at an asynchronous test suite.

While I don't have a final date for when the book site will be ready (or when the book will be available for pre-order) you can be sure that I'll blog about it here, when that's the case (be sure to subscribe to my blog, if you haven't done so already, to receive more updates).

In short: I'm really excited about this book. Progress is going well, the publisher is friendly, the topics are ideal, and the content is coming out great.

Tags: javascript, book, secrets

How JavaScript Timers Work

At a fundamental level it's important to understand how JavaScript timers work. Often times they behave unintuitively because of the single thread which they are in. Let's start by examining the three functions to which we have access that can construct and manipulate timers.

  • var id = setTimeout(fn, delay); - Initiates a single timer which will call the specified function after the delay. The function returns a unique ID with which the timer can be canceled at a later time.
  • var id = setInterval(fn, delay); - Similar to setTimeout but continually calls the function (with a delay every time) until it is canceled.
  • clearInterval(id);, clearTimeout(id); - Accepts a timer ID (returned by either of the aforementioned functions) and stops the timer callback from occurring.

In order to understand how the timers work internally there's one important concept that needs to be explored: timer delay is not guaranteed. Since all JavaScript in a browser executes on a single thread asynchronous events (such as mouse clicks and timers) are only run when there's been an opening in the execution. This is best demonstrated with a diagram, like in the following:


(Click to view full size diagram)

There's a lot of information in this figure to digest but understanding it completely will give you a better realization of how asynchronous JavaScript execution works. This diagram is one dimensional: vertically we have the (wall clock) time, in milliseconds. The blue boxes represent portions of JavaScript being executed. For example the first block of JavaScript executes for approximately 18ms, the mouse click block for approximately 11ms, and so on.

Since JavaScript can only ever execute one piece of code at a time (due to its single-threaded nature) each of these blocks of code are "blocking" the progress of other asynchronous events. This means that when an asynchronous event occurs (like a mouse click, a timer firing, or an XMLHttpRequest completing) it gets queued up to be executed later (how this queueing actually occurs surely varies from browser-to-browser, so consider this to be a simplification).

To start with, within the first block of JavaScript, two timers are initiated: a 10ms setTimeout and a 10ms setInterval. Due to where and when the timer was started it actually fires before we actually complete the first block of code. Note, however, that it does not execute immediately (it is incapable of doing that, because of the threading). Instead that delayed function is queued in order to be executed at the next available moment.

Additionally, within this first JavaScript block we see a mouse click occur. The JavaScript callbacks associated with this asynchronous event (we never know when a user may perform an action, thus it's consider to be asynchronous) are unable to be executed immediately thus, like the initial timer, it is queued to be executed later.

After the initial block of JavaScript finishes executing the browser immediately asks the question: What is waiting to be executed? In this case both a mouse click handler and a timer callback are waiting. The browser then picks one (the mouse click callback) and executes it immediately. The timer will wait until the next possible time, in order to execute.

Note that while mouse click handler is executing the first interval callback executes. As with the timer its handler is queued for later execution. However, note that when the interval is fired again (when the timer handler is executing) this time that handler execution is dropped. If you were to queue up all interval callbacks when a large block of code is executing the result would be a bunch of intervals executing with no delay between them, upon completion. Instead browsers tend to simply wait until no more interval handlers are queued (for the interval in question) before queuing more.

We can, in fact, see that this is the case when a third interval callback fires while the interval, itself, is executing. This shows us an important fact: Intervals don't care about what is currently executing, they will queue indiscriminately, even if it means that the time between callbacks will be sacrificed.

Finally, after the second interval callback is finished executing, we can see that there's nothing left for the JavaScript engine to execute. This means that the browser now waits for a new asynchronous event to occur. We get this at the 50ms mark when the interval fires again. This time, however, there is nothing blocking its execution, so it fires immediately.

Let's take a look at an example to better illustrate the differences between setTimeout and setInterval.

  setTimeout(function(){
    /* Some long block of code... */
    setTimeout(arguments.callee, 10);
  }, 10);
 
  setInterval(function(){
    /* Some long block of code... */
  }, 10);

These two pieces of code may appear to be functionally equivalent, at first glance, but they are not. Notably the setTimeout code will always have at least a 10ms delay after the previous callback execution (it may end up being more, but never less) whereas the setInterval will attempt to execute a callback every 10ms regardless of when the last callback was executed.

There's a lot that we've learned here, let's recap:

  • JavaScript engines only have a single thread, forcing asynchronous events to queue waiting for execution.
  • setTimeout and setInterval are fundamentally different in how they execute asynchronous code.
  • If a timer is blocked from immediately executing it will be delayed until the next possible point of execution (which will be longer than the desired delay).
  • Intervals may execute back-to-back with no delay if they take long enough to execute (longer than the specified delay).

All of this is incredibly important knowledge to build off of. Knowing how a JavaScript engine works, especially with the large number of asynchronous events that typically occur, makes for a great foundation when building an advanced piece of application code.


This is an excerpt from my work-in-progress book: Secrets of the JavaScript Ninja. To be released Fall 2008.

Previous excerpt: Partial Function Application in JavaScript

Tags: book, javascript, secrets

Partial Application in JavaScript

Partially applying a function is a, particularly, interesting technique in which you can pre-fill-in arguments to a function before it is ever executed. In effect, partially applying a function returns a new function which you can call. This is best understood through an example:

  String.prototype.csv = String.prototype.split.partial(/,\s*/);
 
  var results = "John, Resig, Boston".csv();
  alert( (results[1] == "Resig") + " The text values were split properly" );

In the above case we've taken a common function - a String's .split() method - and have pre-filled-in the regular expression upon which to split. The result is a new function, .csv() that we can call at any point to convert a list of comma-separated values into an array. Filling in the first couple arguments of a function (and returning a new function) is typically called currying. With that in mind, let's look at how currying is, roughly, implemented in the Prototype library:

  Function.prototype.curry = function() {
    var fn = this, args = Array.prototype.slice.call(arguments);
    return function() {
      return fn.apply(this, args.concat(
        Array.prototype.slice.call(arguments)));
    };
  };

This is a good case of using a closure to remember state. In this case we want to remember the arguments that were pre-filled-in (args) and transfer them to the newly-constructed function. This new function will have the filled-in arguments and the new arguments concat'd together and passed in. The result is a method that allows us to fill in arguments, giving us a new function that we can use.

Now, this style of partial application is perfectly useful, but we can do better. What if we wanted to fill in any missing argument from a given function - not just the first ones. Implementations of this style of partial application have existed in other languages but Oliver Steele was one of the first to demonstrate it with his Functional.js library. Let's take a look at a possible implementation:

  Function.prototype.partial = function(){
    var fn = this, args = Array.prototype.slice.call(arguments);
    return function(){
      var arg = 0;
      for ( var i = 0; i < args.length && arg < arguments.length; i++ )
        if ( args[i] === undefined )
          args[i] = arguments[arg++];
      return fn.apply(this, args);
    };
  };

This implementation is fundamentally similar to the .curry() method, but has a couple important differences. Notably, when called, the user can specify arguments that will be filled in later by specifying undefined, for it. To accommodate this we have to increase the ability of our arguments-merging technique. Effectively, we have to loop through the arguments that are passed in and look for the appropriate gaps, filling in the missing pieces that were specified.

We already had the example of constructing a string splitting function, above, but let's look at some other ways in which this new functionality could be used. To start we could construct a function that's able to be easily delayed:

  var delay = setTimeout.partial(undefined, 10);
 
  delay(function(){
    alert( "A call to this function will be temporarily delayed." );
  });

This means that we now have a new function, named delay, which we can pass another function in to, at any time, to have it be called asynchronously (after 10 milliseconds).

We could, also create a simple function for binding events:

  var bindClick = document.body.addEventListener
    .partial("click", undefined, false);
 
  bindClick(function(){
    alert( "Click event bound via curried function." );
  });

This technique could be used to construct simple helper methods for event binding in a library. The result would be a simpler API where the end-user wouldn't be inconvenienced by unnecessary function arguments, reducing them to a single function call with the partial application.

In the end we've used closures to easily, and simply, reduce the complexity of some code, easily demonstrating some of the power that functional JavaScript programming has.


This is an excerpt from my work-in-progress book: Secrets of the JavaScript Ninja. To be released Fall 2008.

Tags: programming, book, javascript

· « Previous entries

JavaScript Books

Secrets of the JavaScript Ninja

JavaScript Secrets

Secret techniques of top JavaScript programmers.

Pro JavaScript Techniques

Pro JavaScript

The best techniques for professional JavaScript. Published by Apress.

Micro Updates

John Resig Twitter Updates

@jeresig

Infrequent, short, updates and links.

JavaScript Jobs



Hosting provided by: Ruby Hosting by Engine Yard