PDA

View Full Version : Anonymous Functions and Arguments


mhanson
Apr 27, 2011, 12:59 PM
Currently I'm reading Test-Driven JavaScript Development by Christain Johansen. One of the examples uses a JavaScript version of strftime():

strftime.js


Date.prototype.strftime = (function ()
{
function strftime(format)
{
var date = this;
return (format + "").replace(/%([a-zA-Z])/g,
function (m, f)
{
var formatter = Date.formats && Date.formats[f];
if (typeof formatter == 'function')
{
return formatter.call(Date.formats, date);
}
else if (typeof formatter == 'string')
{
return date.strftime(formatter);
}
return f;
});
}

function zeroPad(num)
{
return (+num < 10 ? '0' : '') + num;
}

Date.formats =
{
d: function (date)
{
return zeroPad(date.getDate());
},

m: function (date)
{
return zeroPad(date.getMonth() + 1);
},

y: function (date)
{
return zeroPad(date.getYear() % 100);
},

Y: function (date)
{
return date.getFullYear();
},

F: '%Y-%m-%d',
D: '%m/%d/%y'
};
return strftime;
} ());

Starting in line 6 the strftime function uses the replace method to return a certain date format. The first part is a regular expression /%([a-zA-Z])/g to identify what needs to be replaced. The second part of the replace method lists the text that will do the replacing. In this example the second part is an anonymous function. When I step through the code using Firefox the arguments (m, f) are passed to the anonymous function. Where are these arguments coming from? How are the determined? Below is the rest of the code.

strftime.test.01-08.js


function assert(message, expr)
{
if (!expr)
{
throw new Error(message);
}
assert.count++;
return true;
}
assert.count = 0;
var date = new Date(2009, 9, 2);

try
{
assert('%Y should return full year', date.strftime("%Y") === '2009');
assert('%m should return month', date.strftime("%m") === '10');
assert('%d should return date', date.strftime("%d") === '02');
assert('%y should return year as two digits', date.strftime("%y") === '09');
assert('%F should act as %Y-%m-%d', date.strftime("%F") === '2009-10-02');
console.log(assert.count + ' tests OK');
}
catch(e)
{
console.log('Test failed: ' + e.message);
}




<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Listing 01-04</title>
<script src="strftime.js" type="text/javascript"></script>
<script src="strftime.test.01-08.js" type="text/javascript"></script>
</head>
<body>

</body>
</html>