{"id":626,"date":"2016-12-05T11:00:39","date_gmt":"2016-12-05T11:00:39","guid":{"rendered":"https:\/\/www.audero.it\/blog\/?p=626"},"modified":"2016-12-04T17:22:22","modified_gmt":"2016-12-04T17:22:22","slug":"monkey-patching-javascript","status":"publish","type":"post","link":"https:\/\/www.audero.it\/blog\/2016\/12\/05\/monkey-patching-javascript\/","title":{"rendered":"Monkey patching in JavaScript"},"content":{"rendered":"<p>When working on a project, we often use libraries that implement methods that aren&#8217;t built-in in the programming language in use. These libraries don&#8217;t cover all the possibilities, so they might lack one or more crucial features we need. When this happens, we have two choices: the first is to create our own module that implements the methods we need, the second is to add those methods to the library itself or to the built-in objects of the language. The latter approach is known as <em>Monkey patching<\/em>.<\/p>\n<p>In this article, we&#8217;ll look at what Monkey patching is, what pros and cons it has, and also a couple of examples that employ this technique.<br \/>\n<!--more--><\/p>\n<h2>What is Monkey patching?<\/h2>\n<p><dfn>Monkey patching<\/dfn> is a technique to add, modify, or suppress the default behavior of a piece of code at runtime without changing its original source code.<\/p>\n<p>It has been extensively used in the past by libraries, such as <a href=\"https:\/\/github.com\/mootools\/mootools-core\" target=\"_blank\">MooTools<\/a>, and developers to add methods that were missing in JavaScript. A well-known example is the <code>endsWith()<\/code> method, which has been introduced in ECMAScript 2015. Before this version, developers had to implement this method themselves. As mentioned before, there are a couple of ways to do that.<\/p>\n<p>One possible approach is to create a <code>Utility<\/code> object that exposes a <code>endsWith()<\/code> method as shown below:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar Utility = {\r\n   endsWith: function(string, suffix) {\r\n      return string.indexOf(suffix, string.length - suffix.length) !== -1;\r\n   }\r\n};\r\n<\/pre>\n<p>With this code in place, the developer would call the method as follows:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar isSuffix = Utility.endsWith('hello world', 'ld');\r\n<\/pre>\n<p>Another approach is to Monkey patch the built-in <code>String<\/code> object to expose the method:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nString.prototype.endsWith = function(suffix) {\r\n   return this.indexOf(suffix, this.length - suffix.length) !== -1;\r\n};\r\n<\/pre>\n<p>With this approach, the developer would call the method as follows:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar isSuffix = 'hello world'.endsWith('ld');\r\n<\/pre>\n<p>At first glance, the second version makes more sense because an <code>endsWith()<\/code> method logically belongs to a string. However, as we&#8217;ll discuss later, this approach can cause several problems.<\/p>\n<p>The <code>endsWith()<\/code> example demonstrates how to use Monkey patching to add a method to a built-in object, but Monkey patching can be used also to change the behavior of a method.<\/p>\n<h3>Using Monkey patching to change a method<\/h3>\n<p>Many developers tend to use <code>console.log()<\/code> when debugging their code. This technique shouldn&#8217;t be used by professional developers, as they should adopt breakpoints and watch variables. For the sake of this discussion, let&#8217;s pretend that <code>console.log()<\/code> is the best way to debug code and that you&#8217;re using it to inspect the value of a variable at different points in time. Everything is working well, but you realize that it would be nice if in addition to printing the value of the variable, the method printed the date at which the method was called. To achieve this goal, you can employ Monkey patching as follows:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ Save the original console.log() method\r\nvar log = console.log;\r\nconsole.log = function() {\r\n   \/\/ Invoke the original method with an additional parameter\r\n   log.apply(console, &#x5B;(new Date()).toString()].concat(arguments));\r\n};\r\n<\/pre>\n<p>In this code, we first save the original <code>console.log()<\/code> method in a variable named <code>log<\/code>. This allows us to reuse the original method whenever we want, as we&#8217;ll see in a moment. Then, we assign an anonymous function to the property <code>log<\/code> of the <code>console<\/code>. In other words, we override the original <code>console.log()<\/code> method. Inside the anonymous function we invoke the original <code>console.log()<\/code> method, stored in the <code>log<\/code> variable, by passing to it all the arguments passed to the anonymous function (through the use of <code>arguments<\/code>) prepended by the current date and time.<\/p>\n<p>Now that we&#8217;ve discussed what Monkey patching is and how to employ it, let&#8217;s examine why it&#8217;s usually considered a bad practice and when it can be helpful.<\/p>\n<h2>The cons of Monkey patching<\/h2>\n<p>Monkey patching is often considered a dangerous technique. Not too long ago, the use of Monkey patching has caused the rename of ECMAScript&#8217;s 2015 method <code>String.prototype.contains()<\/code> to <code>String.prototype.includes()<\/code>. This change was necessary to avoid that websites using MooTools, which adds a <code>contains()<\/code> method to <code>String.prototype<\/code>, were broken due to introduction of the ECMAScript version of the method. In particular, the problem was that the <code>contains()<\/code> method added\u00a0by MooTools and the <code>contains()<\/code> method added\u00a0in ECMAScript 2015 were incompatible. If you want to know more about this topic, you can read <a href=\"https:\/\/developer.mozilla.org\/en\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/String\/includes#String.prototype.contains\" target=\"_blank\">the <code>include()<\/code> method page on MDN<\/a>.<\/p>\n<p>The lesson to learn here is that Monkey patching, especially when used on a built-in object, can interfere with the evolution of the language. This rule can also be extended to any code that you don&#8217;t own, such a library or a framework. Another point to keep in mind when Monkey patching code you don&#8217;t own is that you can never be sure the behavior of the methods you patch. In fact, in the same way you have changed a method, another developer in another part of the software might have done the same. So, chances there are that the two versions will conflict causing issues in the software.<\/p>\n<h2>When to use Monkey patching<\/h2>\n<p>One case where Monkey patching is a good choice is when it&#8217;s used to polyfill methods that are already part of the ECMAScript standard and that are not supported by every browser. This is a safe choice because the method has already been standardized, thus you know its signature and its exact behavior. In addition, by using a defensive technique, you can ensure that you add your own version only if the built-in one isn&#8217;t available. To understand how you can safely employ Monkey patching, let&#8217;s see an example.<\/p>\n<p>As mentioned before, one of the methods introduced in ECMAScript 2015 is <code>String.prototype.includes()<\/code>. It returns <code>true<\/code> if one string is contained within another; <code>false<\/code> otherwise. Its signature is the following:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nString.prototype.includes(searchString&#x5B;, position])\r\n<\/pre>\n<p><code>searchString<\/code> is the string to be searched and <code>position<\/code> is an optional parameter to specify the position at which to begin searching for <code>searchString<\/code>. The default value of <code>position<\/code> is <code>0<\/code>.<\/p>\n<p>To support browsers that don&#8217;t expose the <code>String.prototype.includes()<\/code> method, we can employ Monkey patching as follows:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nString.prototype.includes = function(searchString, position) {\r\n   'use strict';\r\n   if (typeof position !== 'number') {\r\n      start = 0;\r\n   }\r\n\r\n   if (position + searchString.length &gt; this.length) {\r\n      return false;\r\n   } else {\r\n      return this.indexOf(searchString, position) !== -1;\r\n   }\r\n};\r\n<\/pre>\n<p>If we use the previous snippet as is, we also override the native implementation of <code>String.prototype.includes()<\/code> in browsers that support the method natively. To avoid this effect, we should only add the function if it doesn&#8217;t exist in the browser. This can be achieved in two, equivalent ways.<\/p>\n<p>The first solution is to use an <code>if<\/code>:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nif (!String.prototype.includes) {\r\n   String.prototype.includes = function(searchString, position) {\r\n      \/\/ Implementation of the method here...\r\n   };\r\n}\r\n<\/pre>\n<p>Another approach is to use the <code>||<\/code> (OR) logical operator:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nString.prototype.includes = String.prototype.includes || function(searchString, position) {\r\n   \/\/ Implementation of the method here...\r\n};\r\n<\/pre>\n<h2>Conclusions<\/h2>\n<p>In this article, I&#8217;ve covered what Monkey patching is and how it can be used in JavaScript. As we&#8217;ve discussed, in most of the cases Monkey patching is dangerous and can cause issues, therefore you should avoid it. We&#8217;ve also seen a case where Monkey patching a JavaScript built-in object is a good choice: polyfills. Using Monkey patching in conjunction with a defensive technique to polyfill a method that is already part of the ECMAScript standard but it isn&#8217;t supported by some browsers is a great way to avoid creating branches in your code. It also avoids the risk of conflicting with other parts of your software or future features the language.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When working on a project, we often use libraries that implement methods that aren&#8217;t built-in in the programming language in use but we need. These libraries don&#8217;t cover all the possible methods, so they might lack one or more crucial features we need. When this happens, we have two choices: the first is to create our own module that implements the methods we need, the second is to add those methods to the library itself or the built-in classes of the language. The latter is known as <em>Monkey patching<\/em>.<\/p>\n<p>In this article, we&#8217;ll look at what Monkey patching is, what pros and cons it has, and also a couple of examples that employ this technique.<\/p>\n","protected":false},"author":1,"featured_media":632,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[55,72,70,46,69,71,45],"class_list":["post-626","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript","tag-code-style","tag-ecmascript","tag-ecmascript-2015","tag-javascript","tag-monkey-patching","tag-polyfill","tag-standard"],"jetpack_featured_media_url":"https:\/\/www.audero.it\/blog\/wp-content\/uploads\/2016\/12\/monkey-patching.png","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9Or4e-a6","jetpack-related-posts":[{"id":637,"url":"https:\/\/www.audero.it\/blog\/2016\/12\/16\/from-javascript-developer-to-javascript-engineer-re-implementing-ecmascript-2015s-string-prototype-repeat-method\/","url_meta":{"origin":626,"position":0},"title":"From JavaScript developer to JavaScript engineer: re-implementing ECMAScript 2015&#8217;s String.prototype.repeat() method","author":"Aurelio De Rosa","date":"December 16, 2016","format":false,"excerpt":"As developers, our work is to solve problems which often implies writing code. Some of the problems we face look really simple in nature, but their simplicity leads us to write sub-optimal solutions without even realizing it. JavaScript developers come from very different backgrounds, and assuming that everyone has the\u2026","rel":"","context":"In &quot;From JavaScript developer to JavaScript engineer&quot;","block_context":{"text":"From JavaScript developer to JavaScript engineer","link":"https:\/\/www.audero.it\/blog\/category\/javascript\/from-javascript-developer-to-javascript-engineer\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/12\/time-complexity-comparison.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/12\/time-complexity-comparison.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/12\/time-complexity-comparison.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":832,"url":"https:\/\/www.audero.it\/blog\/2018\/07\/20\/5-javascript-interview-questions-a-mid-level-developer-should-be-able-to-answer\/","url_meta":{"origin":626,"position":1},"title":"5 JavaScript interview questions a mid-level developer should be able to answer","author":"Aurelio De Rosa","date":"July 20, 2018","format":false,"excerpt":"According to the results of the 2018's StackOverflow survey, JavaScript is the most popular technology. The amount of job offers for JavaScript developers is constantly increasing and with more companies adopting JavaScript as their main language, it's easy to find good ones. But before you are hired by a company,\u2026","rel":"","context":"In &quot;JavaScript&quot;","block_context":{"text":"JavaScript","link":"https:\/\/www.audero.it\/blog\/category\/javascript\/"},"img":{"alt_text":"job interview panel","src":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/06\/job-interview-panel.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/06\/job-interview-panel.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/06\/job-interview-panel.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/06\/job-interview-panel.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/06\/job-interview-panel.jpg?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":672,"url":"https:\/\/www.audero.it\/blog\/2017\/01\/18\/from-javascript-developer-to-javascript-engineer-find-all-celebrities-in-a-set-of-people\/","url_meta":{"origin":626,"position":2},"title":"From JavaScript developer to JavaScript engineer: find all celebrities in a set of people","author":"Aurelio De Rosa","date":"January 18, 2017","format":false,"excerpt":"In the first article of my series From JavaScript developer to JavaScript engineer titled From JavaScript developer to JavaScript engineer: Re-implementing ECMAScript 2015's String.prototype.repeat() method I've discussed how computer science concepts can help in writing better and more elegant software. Specifically, I've demonstrated how to use appropriate algorithms and data\u2026","rel":"","context":"In &quot;From JavaScript developer to JavaScript engineer&quot;","block_context":{"text":"From JavaScript developer to JavaScript engineer","link":"https:\/\/www.audero.it\/blog\/category\/javascript\/from-javascript-developer-to-javascript-engineer\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/12\/oscars-2014-selfie.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/12\/oscars-2014-selfie.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/12\/oscars-2014-selfie.jpg?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":553,"url":"https:\/\/www.audero.it\/blog\/2016\/08\/03\/power-simplicity-code\/","url_meta":{"origin":626,"position":3},"title":"The power of simplicity in code","author":"Aurelio De Rosa","date":"August 3, 2016","format":false,"excerpt":"A\u00a0few days ago I found an online test\u00a0featuring six exercises on JavaScript. For fun, whishing to challenge myself with something tricky, I decided to take it.\u00a0The test proved to be very simple, so it isn't worth a discussion. It's what happened next that inspired this article. I was talking with\u2026","rel":"","context":"In &quot;Discussions &amp; Opinions&quot;","block_context":{"text":"Discussions &amp; Opinions","link":"https:\/\/www.audero.it\/blog\/category\/discussions-opinions\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/08\/code-simplicity.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/08\/code-simplicity.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/08\/code-simplicity.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":329,"url":"https:\/\/www.audero.it\/blog\/2014\/09\/19\/resources-beginner-front-end-developers\/","url_meta":{"origin":626,"position":4},"title":"Resources for Beginner Front-end Developers","author":"Aurelio De Rosa","date":"September 19, 2014","format":false,"excerpt":"Few weeks ago I received an email from a developer asking me for suggestions on how to delve into the front-end world. After having replied to this email, I thought that it'd have been nice to share the same suggestions on my blog. That's exactly what you'll find in this\u2026","rel":"","context":"In &quot;Discussions &amp; Opinions&quot;","block_context":{"text":"Discussions &amp; Opinions","link":"https:\/\/www.audero.it\/blog\/category\/discussions-opinions\/"},"img":{"alt_text":"html5 css3 javascript logos","src":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2014\/09\/front-end-stack.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2014\/09\/front-end-stack.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2014\/09\/front-end-stack.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2014\/09\/front-end-stack.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2014\/09\/front-end-stack.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":524,"url":"https:\/\/www.audero.it\/blog\/2018\/05\/16\/event-delegation-in-javascript\/","url_meta":{"origin":626,"position":5},"title":"Event delegation in JavaScript","author":"Aurelio De Rosa","date":"May 16, 2018","format":false,"excerpt":"One of the most common tasks a web developer deals with is to add event listeners to the elements of a page. Event listeners are employed to perform one or more actions when a given event occurs on one or more elements. For example, by using an event listener we\u2026","rel":"","context":"In &quot;JavaScript&quot;","block_context":{"text":"JavaScript","link":"https:\/\/www.audero.it\/blog\/category\/javascript\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/08\/event-delegation.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/08\/event-delegation.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/08\/event-delegation.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/08\/event-delegation.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/posts\/626","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/comments?post=626"}],"version-history":[{"count":8,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/posts\/626\/revisions"}],"predecessor-version":[{"id":714,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/posts\/626\/revisions\/714"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/media\/632"}],"wp:attachment":[{"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/media?parent=626"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/categories?post=626"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/tags?post=626"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}