JavaScript function properties

One of my favorite parts of JavaScript is that functions are first-class objects. This might sound trivial but does, in fact, have some very useful implications in that a function is just a type of object with the same behavior as “regular” objects. As an example: a function can return a function, have properties and these can be functions as well. Confused?

If all this sounds a bit messy the example below should illustrate how to use this as well as what it might be used for. The following function helps you build strings in CSV format where you can specify the delimiter to be used.

function CsvDoc(delimiter) {
	var rows = [];

	function inner () {
		rows.push(Array.prototype.slice.call(arguments));
	}

	inner.toString = function() {
		var i, result = '';
		for (i = 0; i < rows.length; i++) {
			result += rows[i].join(delimiter) + '\n';
		}
		return result;
	};

	return inner;
}

can be used as follows

var csv = CsvDoc(';');
csv('Name', 'Age', 'Profession');
csv('Jacob Nielsen', 28, 'Software Developer');
csv('Chiara Delloro', 31, 'Project Manager');
csv('Peter Jennings', 24, 'CEO');

csv.toString(); // <-- Both csv & toString are functions

will yield the following result

Name;Age;Profession
Jacob Nielsen;28;Software Developer
Chiara Delloro;31;Project Manager
Peter Jennings;24;CEO

Why is this special

There are a few things that should catch your eye. First notice that we do not use the keyword new to create an object, instead we make an function invocation of CsvDoc that returns a new function create in the body of CsvDoc. This new function named inner closes over a locally scoped variable inside the CsvDoc body named rows.

Finally our function inner has a property named toString which is also a function closing over the same variable rows.

It means that not only can we create the base function used to build the document but we can also expose other behavior while maintaining the same context/scope.

To make it very clear:

1. The csv variable is not an object instance. No object constructor has been called.
2. The csv variable hold a reference to the newly created function inner.
3. The csv has a property named toString.
4. Both csv & toString close over the same rows reference.

Being able to reference functions from properties on others functions is extremely powerful. It makes JavaScript really stand out. You should keep this feature, of the language, in mind when deciding how to implementing functionality.

Speak Your Mind

*