Wednesday, September 14, 2011

Extending the JavaScript Array type

Here is how I created some expressive code by extending the basic types in JavaScript. This example extends the Array type whose content is often filtered or transposed. Through the use of function chaining complex operations can be very expressive and concise. I find this a great way to write code which is easy to follow.

I wanted to create a cross domain cookie based on the current domain of a page and I was provided with a list of sub domains where this should apply. Interestingly, this list included the name ‘uk’ and ‘cn’ which are also root level domain names.

Here are some example domains:
  • www.keithbloom.co.uk
  • landingpage.keithbloom.co.uk
  • uk.keithbloom.com
  • test.keithbloom.com

Here is a list of sub domains which can be removed:
  • www
  • landingpage
  • uk

Extending the Array

Arrays seemed the obvious choice to me. The domain string can be split on the full stop to create an array and the list of safe sub domains to be removed is already an array. Taking the first example, I end up with the following two arrays:

Now I wish to remove any items in the subDomains which form domainNameParts and return this result.

The subtract function loops over the input and compares each element with each element in the mask array. If it finds a match, the array splice function will remove it. It stops before it reaches the end of the input array though, to avoid removing any of the top level domains. Otherwise my example would return keithbloom.co - useless.

I now have a working function which can be used to create the domain for my cookie:

In the example I use the array function join to re-build my string and append a leading period to it. (For cross domain cookies to work, they must start with a period).

I found this cumbersome though and wanted a more more expressive method. Fortunately, JavaScript is a dynamic language so its internal types can be extended (a technique also know as Monkey Patching). I can add my subtract function to the Array objects prototype:

I now have a more expressive way to create my domain:

The final statement fits on one line. More importantly though it is concise and reads like a sentence. Creating code which is readable is more maintainable.

Pitfalls

This technique is a great way to extend the language and provide an expressive method for writing code. It can be dangerous though. As JavaScript runs as part of a web page there could be other scripts also running on that page. I may find that one of those scripts is also adding a subtract function to the array prototype. If this is a script I have access to, I can rename it. If it is an external script I may have to use a new name.

One way to avoid this is to prefix a namespace to my function:

Summary

Through the extension of the basic types in JavaScript it is possible to create expressive code. The Array type lends itself to this technique as they are often used as lists which we wish to manipulate in some way. Care must be taken though as we are changing code for all the programs being run in the session.