Showing posts with label Patterns. Show all posts
Showing posts with label Patterns. Show all posts

Saturday, July 17, 2010

JavaScript - apply invocation pattern part 2

In my last post I promised a real-world example of the apply invocation pattern. The truth is it was getting late, and I didn't feel like writing anymore. However, one of my coworkers called me out, most likely because he's a JavaScript ninja and wants to put me in my place. In an effort to deny him the satisfaction, I'll steal an example from people who are smarter than I.

If you use jQuery, you've probably used the each function at some point. The each function works something like this (what follows is a vast oversimplification, see here for the actual implementation):

jQuery.extend({
  each: function(array, callback) {
    for (var i = 0; i < array.length; i++) {
      var value = array[i];

      //Apply callback with "this" as the current value
      callback.apply(value, [i, value]);
    }
  }
});

Now we can use the each function like this:

var sentence = '';
var words = ['hello', ' ', 'world', '!'];
jQuery.each(words, function() {
  sentence += this;
});
//sentence == 'hello world!'

Tuesday, July 13, 2010

Things your parents never told you about JavaScript - Apply invocation pattern

So, yeah, it's been a while... okay, it's been more than a while. I'm sure my 8 followers missed me. Anyway, I recently had the opportunity to learn a whole mess of new stuff, and I wanted to start writing some of it down. I had a 3 week fling with Ruby, followed by a longer affair with JavaScript. I was a static language guy for the last 3 years, so all this dynamic nonsense had my head spinning... and you know what?

I liked it.

I always thought of JavaScript development as painful; a sort of necessary evil. Turns out there's an obscenely powerful language there, if you go looking for it (incidentally, start by looking here). Among those powerful features are first-class functions. For example, suppose I run the following code:

var greeter = {
  name: 'Mike',
  greet: function() {
    return 'hello ' + this.name;
  }
};

greeter.greet(); // -> 'hello Mike'

Nothing shocking there, right? Well, I can actually reach into the greeter object and steal the greet function:

var greet = greeter.greet;
greet(); // -> 'hello '

Okay, kind of cool, but not quite the expected result. Where did my name go? When you grab a function that references this and invoke it, you need to tell JavaScript what context you want to execute it in. The built-in JavaScript Function object has a method called apply which lets you set the value of this (it also lets you pass an argument array if you want to):

var bob = {
  name: 'Bob'
};

greet.apply(bob); // -> 'hello Bob'

This is called the apply invocation pattern. What can you do with it? That'll have to wait for another post...