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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var domainNameParts = “www.keithbloom.co.uk”.split(‘.’); // returns [‘www’,’keithbloom’,’co’,’uk’] | |
var subDomains = [‘www’,’landingpages’,’uk’]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var subtract = function(input, mask) { | |
for (i = 0; i < input.length - 1; i++) { | |
for(j = 0; j <= mask.length; j++) { | |
if(input[i] == mask[j]) | |
input.splice(i,1); | |
} | |
} | |
return input; | |
}; | |
var result = subtract(domainNameParts, subDomains); |
I now have a working function which can be used to create the domain for my cookie:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var cookieDomain = '.' + subtract(domainNameParts, subDomains).join('.'); |
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Array.prototype.subtract = function(mask) { | |
for (i = 0; i < this.length - 1; i++) { | |
for (j = 0; j <= mask.length; j++) { | |
if (this[i] === mask[j]) { | |
this.splice(i, 1); | |
} | |
} | |
} | |
return this; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var cookieDomain = '.' + 'www.keithbloom.co.uk'.split('.').subtract(subDomains).join('.'); |
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Array.porototype.a_namespace_subtract = function() … |