Sergio and the sigil

Have you met arguments.callee?

Posted by Sergio on 2010-09-10

Just the other day I had a need to use arguments.callee and I realized that's not something you really see every day in JavaScript. Maybe I could talk about it a bit.

Anonymous functions everywhere

It's not news to anyone reading this blog that one of JavaScript's workhorses are anonymous functions. Callbacks, strategies, deferred execution, event handlers, etc. They just seem to be all over the place — and for a good reason; they can be convenient and reduce the pollution of a bunch functions that are only called from a single spot.

Another nice thing is that, once your eyes are trained to ignore the little bit of noise that they add to the code, the code is really readable and, dare I say it, expressive.

Yet another contrived example

Let's say we are really into reinventing the wheel and with our understanding of anonymous functions we create a revolutionary map function:

function map(array, compute){
  var result = [ ];
  for(var i=0; i < array.length; i++){
    result.push( compute(array[i]) );
  }
  return result;
}

This function, as you can hopefully see, transforms each element of the given array into something else and returns the array of the transformed elements. Two simple uses are shown below.

//apply discount
var prices = [1, 2, 3, 4];
var discount = 0.1; // 10% off today, w00t!
var newPrices = map(prices, function(price){ return (1-discount)*price; } );
//==> [0.9, 1.8, 2.7, 3.6]

//compute areas
var squareSides = [1, 2, 3, 4];
var squareAreas = map(squareSides, function(side){ return side*side; } );
//==> [1, 4, 9, 16]

I warned you the examples would be contrived, didn't I?

Now your product manager comes and asks for a page where the users can enter a list of numbers and get the factorials for each of them. You immediately think your friend the map function will save the day. You start and...

//return the factorials
var userNumbers = [1, 2, 3, 4];
var factorials = map(userNumbers, function(number){ 
  if(number <= 1) { return 1; }
  return number * ????????(number - 1); // ooops! I need to recurse here.
} );

You see, there's this thing with anonymous functions. They don't have a name, d'oh. As I said in the beginning, we typically use them in situations where they are called only once so we can inline them and forego the need fora name. But now we're kind of wishing they had a name.

Anonymity won't hide you from me

Well, if the post tittle didn't already give it away, we can achieve that with arguments.callee. Using arguments.callee inside a function gives us a reference to the function itself. So now we can finish our code.

//return the factorials
var userNumbers = [1, 2, 3, 4];
var factorials = map(userNumbers, function(number){ 
  if(number <= 1) { return 1; }
  return number * arguments.callee(number - 1);
  //or if you were using "this" in the function you'll probably want to:
  // return number * arguments.callee.apply(this, [number - 1]);
} );
//==> [1, 2, 6, 24]

A more real world scenario

I won't leave you without at least a reference to a real use case for this feature. The example I'll show comes from Nicholas Zakas. In a blog post a while ago he showed how we can break up long running tasks with smaller timed/deferred chunks, improving the browser's responsiveness.

Here's the function from his blog post, which process chunks of an array for 50ms, then stops and call itself back to process the remaining items soon after that — giving the browser a chance to breathe and take care of its interaction with the user

//Copyright 2009 Nicholas C. Zakas. All rights reserved.
//MIT Licensed
function timedChunk(items, process, context, callback){
   var todo = items.concat();   //create a clone of the original

  setTimeout(function(){

    var start = +new Date();

    do {
       process.call(context, todo.shift());
    } while (todo.length > 0 && (+new Date() - start < 50));

    if (todo.length > 0){
      setTimeout(arguments.callee, 25);
    } else {
      callback(items);
    }
  }, 25);
}

I hope this shows you a little new trick.

JavaScript and its love for zeroes

Posted by Sergio on 2009-09-19
This post is part of a series called JavaScript Demystified.

Answer quick. Do you know what date is being created here?

var year = '2009', month = '09', day = '01';
var date = new Date( 
             parseInt(year),
			 parseInt(month),
			 parseInt(day)
			 );	

At first glance, it wouldn't surprising that someone guesseed September 1st 2009. However, I'd not be writing this post if that was the correct answer, right?

There's an interesting and tricky thing with the JavaScript parseInt function: it can parse strings with a numeric value in the decimal radix, but also in other radices. See the following examples.

//passing the radix explicitly
parseInt('1011', 10); // ==> 1011
parseInt('1011',  2); // ==> 11
parseInt('1011',  8); // ==> 521
parseInt('1011', 16); // ==> 4113

Maybe you thought that if you didn't pass the radix, then it would default to 10 because it's the obvious behavior. Well, no. In JavaScript the default behavior is to try to identify one of the literal formats and interpret that. So here's that in action:

//leaving JavaScript on its own
parseInt('1011'); // ==> 1011 (decimal literal)
parseInt('0x12'); // ==> 18   (hexadecimal literal)
parseInt('0511'); // ==> 329  (octal literal)
parseInt('0182'); // ==> 1    (whaaaa?!?!)

If you are familiar with the literal notation for integer numbers in JavaScript, and after I explained the default behavior of parseInt, then you probaly understood the results shown above. Well, maybe the last one deserves some comments.

When JavaScript is parsing the string, if it finds a digit (number or alpha) that is invalid in the chosen radix, it stops right there and parses only the portion of the string that comes before that digit. So, since we started '0182' with a leading zero, the octal radix is assumed. Then, because 8 is not a valid octal digit, only '01' will be parsed, which becomes 1.

Tip #1: If there's any chance the string value you plan to parse into an integer number has a leading zero (or a less likely 0x,) then be safe and pass the radix parameter to your parseInt call. If you're extra paranoid, then always pass the radix.

Back to our original question

Armed with the clarification made above, we can expand our example like this:

//given:
var year = '2009', month = '09', day = '01';
// then the following statement:
var date = new Date( 
         parseInt(year),
         parseInt(month),
         parseInt(day)
         );	
//...is equivalent to:
var date = new Date( 
         2009,
         0,  // ===> oopsie
         1
         );	

Hmmm, a zero in the month parameter. Will we have an error here? No, here comes the second potential surprise of this post.

Tip #2: When creating a new date using new Date(year, month, day), the month parameter, and only the month parameter is zero-based (0 to 11).

So, in case the tips and the picture in this text were not enough to help you guessing the date being created, here goes another completely gratuitous one with the answer.

JavaScript: Not your father's inheritance model - Part 1

Posted by Sergio on 2009-06-12
This post is part of a series called JavaScript Demystified.

This particular chapter is further divided in two parts. Read Part 2.

In a previous installment in this series we saw how we could create constructor functions in JavaScript. Back then I just mentioned that we don't have classes in JavaScript and that there's this weird prototype property in every object.

Let's dig into those concepts a little more and try to understand how inheritance is achieved in JavaScript.

Inheritance as we often know it

For myself and probably the majority of you reading this blog, inheritance in an Object Oriented programming language is directly associated with the concept of classes.

When we work with C#, VB, Java, Ruby, and many other popular programming languages, each of our objects is of some type, which is represented by a class. Our objects automatically inherit functionality from their associated class often called base or super class, and any other classes that the base class itself is associated with (i.e. derives from.)

That's nothing new to you, I'm sure. I'm just re-hashing that in the previous paragraph to make a comparison later. Let's call this model class-based inheritance.

That's not the end of the story

This may come as a surprise to some people, but class-based inheritance is not the only way to obtain Object Oriented inheritance (by saying Object Oriented I automatically excluded those of you that thought Copy/Paste Inheritance was one of them.)

It just so happens that the JavaScript language designers chose another inheritance model. And they are not alone in that choice. By opting for a prototype-based inheritance model , JavaScript joined the ranks of other programming languages such as Self , Lua , and Agora.

The prototype is the king

Objects in JavaScript don't inherit from classes; they inherit straight from other objects. The object they inherit from is called their Prototype (I'm using a capital P here to avoid confusion down the line.) The object's Prototype is assigned right at construction time.

You may be intrigued and say: But when I create my objects I don't remember specifying any Prototype stuff. What gives?

Let's see what happens then. When you create a plain Object using either of the following syntaxes

var obj1 = new Object();
obj1.name = 'box'
//or
var obj2 = { name: 'door' };

JavaScript will automatically assign a Prototype to each of these objects. This prototype will be Object.prototype.

Similarly, let's see what happens with a few of the other object types in JavaScript.

The Prototype objects is how every object in JavaScript is born with inherited functionality. For example, the substring() method that every String object has is a method defined in the object String.Prototype.

The prototype objects themselves also inherit from Object.prototype, that's how every object of any type has a toString() method.

When you try to access 1234.constructor, as an example, the runtime will look for a constructor property on our object (the number 1234). It doesn't have one so the next step taken is to check if that object's Prototype has it. The Prototype for 1234 is Number.prototype and it doesn't have that property either. The runtime then looks on the Prototype of Number.prototype, which is Object.prototype. That last object does have a constructor property, so that is returned. If it didn't, undefined would have been returned instead.

In Part 2 we will see how to create our own Prototypes.

JavaScript: Not your father's inheritance model - Part 2

Posted by Sergio on 2009-06-12
This post is part of a series called JavaScript Demystified.

This particular chapter is further divided in two parts. Read Part 1.

Build your own hierarchy

Let's pretend we are building some scripts that deal with musical instruments. We could define our own Guitar class type like this:

//The constructor
function Guitar(brand, model) {
    this.brand = brand;
    this.model = model;
    this.strings = ['E', 'A', 'D', 'G', 'B', 'e'];
}

//Instance methods
Guitar.prototype = {
    play: function (chord) {
        alert('Playing ' + chord); 
    },
    toString: function () {
        return '(Guitar: ' + 
            this.brand + ' ' +
            this.model + ')';
    }
};

var guitar1 = new Guitar('Gibson', 'Les Paul');

What may not be apparent by just looking at the code for the first time is that guitar1's Prototype will be Guitar.prototype, which means that guitar1 inherits from Guitar.prototype. Also guitar1.constructor === Guitar.

When the last line in the above example is executed, the JavaScript runtime will take care of initializing a new object that has Guitar.prototype as its Prototype and makes its constructor property point to the Guitar function.

But what if we want to create a different type of guitars and still reuse the existing Guitar type. We could do this:

function BassGuitar(brand, model) {
    //call the constructor of our base type
    Guitar.apply(this, [brand, model] );
    //change or add anything we wish
    this.strings = ['E', 'A', 'D', 'G'];
}

//Copy the Prototype of our base type
BassGuitar.prototype = Object.create(Guitar.prototype);

//Override whatever we want:
BassGuitar.prototype.toString = function () {
    return '(BassGuitar: ' + 
        this.brand + ' ' +
        this.model + ')';
};

var bass1 = new BassGuitar('Peavey', 'Cirrus');
bass1.toString(); //=> '(BassGuitar: Peavey Cirrus)'
alert(bass1.strings); //=> [ 'E', 'A', 'D', 'G' ]

But there's a problem with the above code. There isn't a method Object.create(). Yeah, that's one of the design omissions in JavaScript. Any prototype-based language needs an easy way to let use create objects from other objects.

Thankfully JavaScript is also dynamically typed, so we can add that function ourselves. Here I'm borrowing from Douglas Crockford.

//add this to the very beginning of your scripts
if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

I'll leave the interpretation of the above function as an exercise to the reader. Once you understand what it is doing you will have mastered prototypes and constructors.

Handy Prototype tricks

Knowing what we know now and once again leveraging JavaScript's dynamism we can fix one of the things that has always annoyed me in JavaScript: the lack of a trim() method on strings.

String.prototype.trim = function () {
    return this.replace( /^\s*(\S*(\s+\S+)*)\s*$/, "$1"); 
}; 
var text = ' some user-entered value   ';
alert( text.trim() ); // => 'some user-entered value'

How about an easy way to pad numbers with zeroes?

Number.prototype.padLeft = function (width) {
    var text = this.toString();
    for(; text.length < width; ){
        text = '0' + text;
    }
    return text;
};

var num = 1234;
alert(num.padLeft(6)); // => 001234

Why do I need to know all this stuff?

Well, you don't. But why even bother writing JavaScript code if you're not willing to learn how it works?

As we have been seeing during this series, JavaScript bears only some syntax similarities with C# or Java. Underneath the surface it has been designed very differently. The web is riddled with attempts to mimic class-based inheritance in JavaScript only because programmers don't want to learn and leverage prototype-based logic.

My humble advice is that you will feel happier and smarter if you chose to learn how to use the language as it was intended.

JavaScript: Avoid the Evil eval

Posted by Sergio on 2009-03-31
This post is part of a series called JavaScript Demystified.

I'm pretty sure by now you have heard at least once that eval is evil. Some nuggets from Eric Lippert's post:

if you are considering using eval then there is probably a better way
People, eval starts a compiler.

I'm also pretty sure I don't need to tell you that anytime you have an explicit eval() in your code, there's a good chance it's there because you're not taking JavaScript seriously yet.

//mandatory square brackets notation example
//------------------------------------------
var myObject = new MyObject();
var prop1 = eval( 'myObject.' + somePropertyName ); // BAD!
var prop2 = myObject[ somePropertyName ]; // Better

That's not the end of all eval()

At this point some people might be feeling relieved: "Phew! That was easier than it sounded. Getting rid of eval is a piece of cake." Well, I'm not going to say it's significantly harder than that, but we're not done prunning eval() from our code just yet.

You see, eval() is like that coward opponent that sneaks in the dark to attack you from behind. Let's find some of eval's favorite hiding places.

There's a time when you need a timer

Two very popular JavaScript functions used to create timers are setTimeout() and setInterval(). Here's how you still find code being written to use them.

function doSomething(someValue){
	//...
}

setTimeout("doSomething('3 seconds elapsed. Time is up.');", 3000);

As it turns out, this is just another occurrence of eval() revealing how incompetent we can still be in this programming language. Here's a better way to write that code.

setTimeout( function(){ 
                doSomething('3 seconds elapsed. Time is up.');
            }, 
            3000);

Thank God I didn't know functions had constructors

The other secret place that eval() likes to hang out is in the Function constructor. Fortunately this isn't exactly a popular way of creating functions. I'll say it: I didn't even know about this constructor until less than a couple of years ago.

So, in case you don't know what I'm talking about here, I'll show you how to use the function constructor just to imemdiately tell you to not do it.

var sum = new Function('op1', 'op2', 'return op1 + op2;');
var result = sum(10, 20); // ==> 30

The above code is roughly equivalent to the explicit eval() usage below.

eval("var sum = function (op1, op2) { return op1 + op2; }");
var result = sum(10, 20); // ==> 30

We don't come up with the need to use the function constructor often, but I'll admit that when we do, it's usually hard to replace it with another way that doesn't use eval().

Minor update: I was doing some snooping around with Firebug and Reflector and found that WebUIValidation.js (embedded in System.Web.dll) does use eval() in some ways that I just pointed out to be unnecessary. If that is of any comfort to anyone that has done the same in the past, there you have probably the largest deployment of misused eval() I know of.