Get friendly with the Natives

Written By Ryan Florence, on Tuesday, March 23rd 2010, 9:48pm

Have you extended a Native lately? It’s an incredibly helpful thing. Often people write ugly functions that take a string or whatever as an argument and return some manipulation of the string. Extending natives is a great way to do the same thing, but it is much prettier (aka: explicit, readable, easier-to-debug.)

The Difference:

I’ve seen stuff like this:

fn1(fn2(10, fn3('house')));

Hard to figure out what’s happening. Instead you can write code like:

fn3('house').fn2(10).fn1();    

A Useful, Real Example, zeroPad

I’ve used this in a couple scripts, it takes a number and returns a string with zeros padded in front: 123 becomes ‘000123’. Really handy for filenames and the like. Here’s the ugly version:

Functionally Based Example

function zeroPad(num, zeros){
  zeros = zeros || 3;
  var str = '' + num;
  zeros.times(function(){ str = '0'+str; });
  return str;
};

// usage
doSomething(zeroPad(document.getElementById('myInput').value, 3));

Native Extentions Based Example

Number.implement({
  zeroPad: function(zeros){
    var str = '' + this;
    zeros.times(function(){ str = '0'+str; });
    return str;
  }
});

// so that it works on both numbers and strings
String.implement({
  zeroPad: function(zeros){
    return this.toInt().zeroPad(zeros);
  }
});

// usage
$('myInput').get('value').zeroPad(3).doSomething();

Side by Side:

doSomething(zeroPad(document.getElementById('myInput').value, 3));
// vs
$('myInput').get('value').zeroPad(3).doSomething();

Awesome? Yes. You can do the same thing to:

Some say extending natives is a bad idea. Personally, I think it’s awesome—but this topic is a sore spot for some. Extending natives is a feature of javascript itself that any general application framework like MooTools is entitled to use. There could be an entire article dedicated to this topic but this article isn’t it. This article is simply here to show how to use this handy feature.

Flippin’ Sweet Array methods

Arian Stolwijk created this amazing gem: Array.Math. Code samples often tell the story faster:

[2,5,1,6].sum(); // 14
[2,5,6,2].product(3); // [6,15,18,6]
[9,12,15].quotient(3) // [3,4,5]

This is all made possible by extending the Array native, see?

    Array.implement({

        sum: function(start,length){
            var sum = 0, 
                start = start ? start : 0,
                length = length ? length : this.count()-start;
            length = start ? length + 2 : length;
            for(var i=start;i<length;i++) sum += this[i];
            return sum;
        },

        product: function(p){
            var arr = $type(p) == 'array';
            return this.map(function(entity,i){
                return arr ? (entity * p[i]) : (entity * p);
            });
        },

        quotient: function(q){
            var arr = $type(q) == 'array';
            return this.map(function(entity,i){
                return arr ? (entity / q[i]) : (entity / q);
            });
        },

        // and a whole lot more awesome ...

    });

Quick Tips

  • this is the number or string, or whatever, when inside the method.
  • Return something that makes sense (usually this).
  • You can implement several methods all in the same code block.

This is just one more great tool to help keep your code organized and readable.

4 Responses to “Get friendly with the Natives”

  1. Arian says:

    Cool that you used Array.Math as an example !

    Nice article btw and congrats with your first article on the MooTools Blog

  2. T.J. Leahy says:

    I love extending the natives, it makes coding so much faster and easier to read. Nothing like my Array.unique() function for taking [0, 1, 2, 3, 1, 3] to [0, 1, 2, 3] or similar functions. I have a whole “natives” file I use on every project to make working with natives work better.

  3. Tristan says:

    You say some people think it’s a bad idea to extend natives, now I wonder who’s saying that and why they think so. Can anyone give me some insight in this? I like to know both sides of a story.

  4. Arian says:

    @Tristan: Because some people say it polutes the js and it can give troubles with some other scripts that use the same thing. However Native.implement will not overwrite already existing methods.

    Also look at this blogpost on the MooTools blog, also about natives: http://mootools.net/blog/2007/10/31/mootools-foundations-natives-and-elements/