Understanding Monkey Patching in Javascript

Explore JavaScript's monkey patching: dynamically modify or extend object/function behavior without altering source code. Dive in!

Understanding Monkey Patching in Javascript
Photo by Syed Ahmad / Unsplash

Discover the art of monkey patching in JavaScript, a technique where you tweak or expand the functionalities of existing objects or functions during runtime. Dive into this article to delve deeper into the world of monkey patching and its applications in JavaScript programming.

JavaScript operates on a prototype-based system, where objects can inherit properties and methods from other objects. This sets it apart from class-based languages such as Java or C++, where objects originate from classes, and inheritance is structured through class hierarchies.

In JavaScript, every object is linked to another object called its prototype. This prototype object, in turn, has its own prototype, creating a chain known as the prototype chain. When you access a property or method on an object in JavaScript, the language first checks if that property or method exists directly on the object itself. If it doesn't find it, JavaScript then looks at the object's prototype, and if it's not there, it continues up the prototype chain until it locates the property or method, or until it reaches an object with a null prototype.

prototype chain

JavaScript's prototypal nature carries significant implications. It enables dynamic inheritance since prototypes are objects that can be altered during runtime. Consequently, modifications to a prototype affect all objects inheriting from it. While this dynamic behavior offers flexibility, it can also result in unintended side effects if not managed meticulously.

Moreover, this dynamic aspect facilitates monkey patching, enabling the alteration of an object or its prototype even after the object's creation.

Techniques Monkey Patching

You can accomplish monkey patching in JavaScript through various methods. These include:

How To Extend Object Prototypes

Extending object prototypes in JavaScript enables you to incorporate custom methods or properties into built-in JavaScript objects such as Object, Array, and String.

To achieve this, you access the prototype property of the object you wish to extend and append your implementation. For instance, to expand the functionality of the String object, you invoke String.prototype.<your new function>.

For instance:

String.prototype.isUppercase = str => str === str.toUpperCase();;

console.log('isUppercase'.isUppercase());
// logs false

console.log('ISUPPERCASE'.isUppercase());
// logs true

monkey patching example string prototype

The provided code snippet extends the functionality of the String object by introducing a new method named isUppercase. This method checks if a string is uppercase and returns either true or false.

As a result, every string in your codebase gains access to the isUppercase function, even though it isn't part of the original string methods.

This technique of extending object functionalities, known as monkey patching, is applicable to all JavaScript objects with a prototype chain, including the Array object.

Array.prototype.multiplyBy = function (multiplier) {
  return this.map(number => number * multiplier)
};

const arr = [1, 2, 3, 4, 5];

arr.multiplyBy(2);

monkey patching array prototype

The code block above adds a method that multiplies all the elements of an array by the multiplier argument passed.

Here's how you can implement monkey patching by extending the prototype of an object.

Overriding and Extending Existing Methods

Another approach to monkey patching involves extending or overriding an existing method. This method entails creating a copy or reference of the original method before modifying it, allowing you to retain access to the original behavior if necessary.

For instance, you can extend the functionality of the Array.forEach method to log when forEach have been called.

const originalForEach = Array.prototype.forEach;

Array.prototype.forEach = function (callback) {
  const originalArray = this;
  const originalForEachdArray = originalForEach.call(originalArray, callback);

  console.log("Called Foreach: ", originalArray);
};

const arr = [1, 2, 3, 4, 5];

arr.forEach((item) => {
  // do something with item
});

monkey patching array forEach

The code would return something like:

// Called Foreach: [1, 2, 3, 4, 5]

output of monkey patching forEach method

Problems and Limitations of Monkey Patching

Monkey patching, although powerful in JavaScript, presents several pitfalls and limitations that warrant caution. These include:

Polluting The Global Scope

Global scope pollution occurs when numerous variables, functions, or objects clutter the global scope, potentially causing unintended behaviors.

Monkey patching makes global scope pollution by adding or modifying properties and methods on built-in prototypes or objects. Such alterations can trigger naming conflicts and bugs, particularly in scenarios involving multiple libraries or codebases.

Issues On Compatibility

Monkey patching can create compatibility issues, especially when interacting with third-party libraries or various JavaScript environments like browsers or Node.js. Modifying built-in objects may not behave consistently across different environments or versions. Consequently, it's usually safer to refrain from altering built-in methods unless there's a compelling necessity.

Violation of Encapsulation Principles

Monkey patching in JavaScript can undermine encapsulation principles, which are essential to object-oriented programming. Encapsulation advocates for hiding an object's internal state and allowing access only through well-defined interfaces, typically methods. However, when you monkey patch an object or class, you often need to access and modify its internal state directly, potentially violating encapsulation principles.

Conclusion

Monkey patching serves as a potent method for dynamically extending or altering existing code. Nonetheless, its implementation demands awareness of the prototype chain, a commitment to preventing global scope pollution, and the preservation of encapsulation.

Practicing caution, documenting alterations, and rigorously testing patches are crucial steps in implementing monkey patching to alleviate compatibility concerns and security vulnerabilities.

It's important to recognize that alternative methodologies such as object composition and class inheritance offer more organized and sustainable solutions for software development.

Devqaly: A Cut Above the Rest

Now, let's explore why Devqaly stands out as a superior session recording tool compared to its competitors.

  1. Record Database Transactions:
    Devqaly's backend integration allows developers to see not just the frontend interactions but also the associated database transactions. This feature is invaluable in spotting issues such as N+1 problems, providing a interconnected view of the application's performance.
  2. Real Video Recording:
    While other session recording tools may simulate video-like implementations, Devqaly takes it a step further by recording real video. This means developers can gain context not only within the application but also outside of it, offering a more refined understanding of user interactions.
  3. Create Custom Events:
    Devqaly empowers developers by allowing them to create custom events. This flexibility ensures that developers can tailor session recording to their specific needs, enhancing the tool's adaptability to diverse debugging scenarios.
  4. Open Source Advantage:
    Devqaly's open-source nature gives developers the freedom to host their own instances in their infrastructure. This not only provides greater control over the tool's deployment but also ensures compliance with internal security policies.
  5. Own Your Data:
    Security and data ownership are important concerns. Devqaly addresses this by allowing users to own 100% of their data. Hosting your own instance means that no data ever reaches Devqaly's servers, providing a robust solution for organisations with stringent data privacy requirements.

Subscribe to devqaly

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe