I hope you all know about Douglas Crockfords website, but if you don’t, he has this wonderful little post called Remedial JavaScript. Which as you might imagine contains some basic JavaScript features, that were more or less, left out of the language. One of my favorites, is the supplant() prototype method. If your from a .NET or Java background you probably would recognize it better as String.Format().

Lets check out the prototype.

  1. String.prototype.supplant = function (o) {
  2. return this.replace(/{([^{}]*)}/g,
  3. function (a, b) {
  4. var r = o[b];
  5. return typeof r === 'string' || typeof r === 'number' ? r : a;
  6. }
  7. );
  8. };

This prototype takes in an object with properties matching the bracketed pairs in your string.

  1. "The date today is {todayDate}, thank you {name}".supplant(
  2.  
  3. { "todayDate" : new Date().toString(), "name" : "Clark Kent" }
  4.  
  5. );

Its just so beautiful and small, one can’t help but wonder how such it works.We have our traditional regex to match the bracketed keys in our string, which is easy enough, though the real magic here is discovering you can pass a function to the replace method, which allows you to do some custom magic on the replaced value.

He also does some additional type checking to be sure we are not assigning methods or anything else weird to our string values ([object Object] would look pretty stupid), but thats about it.  Something so easily implemented and useful, why isn’t it just part of the Language already?

2 comments

2 Responses to ““string”.supplant() a jewel from Douglas Crockford”

  1. Kris “Justise” Gray » Format strings with Mootools Says:

    […] Remember String.Supplant()? […]

  2. Ruben Says:

    Douglas Crockford’s jewel handles just one level object hierarchy.
    Following small modification handles any object.
    Placeholders now can include dotted notation – {foo.boo.moo.uff….}.
    I call it present() – because it looks ideal for presenting preformatted object’s values
    String.prototype.present = function(o)
    { return this.replace(/{([^{}]*)}/g,
    function(a, b)
    {
    var p = b.split(‘.’);
    var r = o;
    try
    {
    for(s in pat) {r = r[p[s]]};
    }
    catch(e){ r = a;}
    return typeof r === ‘string’ || typeof r === ‘number’ ? r : a;
    }
    );
    };

Leave a Reply