Monkeying around with Monkey patching.

Coming from a language like Ruby to Javascript can leave the programmer with a desire for the missing features, syntax and just overall easily read code. Things as simple as the reversing of a string that require one to make a new function as opposed to simply saying ‘gnirts’.reverse. So how can we add a little extra functionality to our project without having to repeat ourselves?

Enter Monkey Patching! Monkey patching put simply is altering the behaviour of existing code without modifying the code itself. This can mean anything from extending the behaviour of a data type, to completely suppressing existing functions.

Lets get the elephant out of the way: Monkey Patching is a bad practice. While making a couple of small changes here and there for experimental reasons won’t break your code, using it in actual products can result in many unintended behaviours, especially when overriding the behaviour of existing methods, or when different sources(i.e. libraries or modules) attempt to change the same functionality.

Note: Patching up a kung fu monkey’s attire is not a regular part of the experience

With that out of the way, lets get down to how we actually Monkey Patch in JS. The first, and safest approach is to create an object that will hold all of our monkey patched functions in it. For this example lets add a reverse functionality:

var Utility = {
reverse: function rec(string){
return string === '' ? ''
: rec(string.substring(1)) + string.charAt(0);
}
}

Once our object is defined, we can simply call it by referencing the object and calling the reverse property, which houses our recursive reverse function. Like so:

var reverseMe = "gnirts"
console.log(Utility.reverse(reverseMe)); => 'string'

As we can see we are not doing much to any existing code itself, just adding a hover of functionality in an easy to access manner. In doing so we can then export this object into other files and use our Utility functions. Nonetheless, we can also directly influence the String.prototype in our second, albeit more dangerous, method for monkey patching that I’ll cover. To do so just call the prototype you want to modify, and give it a function:

String.prototype.stringMap = function(){ 
return 'I am stringMap';
}
'ayy'.stringMap(); => 'I am stringMap'

Great! We now have a working extension to our prototype, lets build a method that allows us to use the functionality of Array.map on a string, by splitting the string into an array-> mapping our changes with some parameters-> and rejoining the array into a string.

String.prototype.stringMap = function(change ,replace=false,splitBy = ''){
if(replace){
return this.split(splitBy).map(el=>change).join(splitBy);
}
return this.split(splitBy).map(el=>el += change).join(splitBy);
};

console.log('Add a period after every space'.stringMap('.', false,' ')); // => "Add. a. period. after. every. space."
console.log('replace word with \'franisawesome\'.'.stringMap('franisawesome',true,' ')); 
//=> franisawesome franisawesome franisawesome franisawesome

As you can probably tell, this stringMap method is not very robust, and does not incorporate the full functionality of what an array map can do; however, we have now monkey patched the String.prototype and added our own custom functions to the language, how cool is that?

I do not claim to be an expert on monkey patching, nor do I advocate its use in projects, but I think it is an interesting concept to monkey around with.

Hope you enjoyed the entry!