Monkey patching is the term used for this practice.
https://en.wikipedia.org/wiki/Monkey_patch
Your example of monkey patching is seen as malicious and is generally discouraged because it can break code that relies on Object.assign
.
In the case of this specific example, a better alternative could be:
{
let assign;
[assign, Object.assign] = [Object.assign, function(dst, ...sources){
if(sources.at(-1) === 'deep-copy'){
return assign.call(Object, dst, ...sources.slice(0, -1).map(src => structuredClone(src)));
}
return assign.apply(Object, arguments);
}]
}
const a = {};
const b = {prop:{test:true}};
Object.assign(a, b, 'deep-copy');
b.prop.test = false;
console.log(a);
Object.assignDeepCopy()
may seem like a more concise and safer solution, but there is a risk of potential conflicts with future JavaScript additions...
Unfortunately, in cases involving Object.assign
, there isn't a foolproof solution...
The recommended approach would be simply:
Object.assign(a, structuredClone(b));
It's worth noting that opinions vary on whether monkey patching is a good practice or not.
I personally appreciate monkey patching BUT:
- Using monkey patching within your project is generally acceptable.
- When implementing monkey patching, maintaining the default behavior while adding extra functionality is crucial.
- If you are providing code for others to use (e.g., a framework, module, or library), then it's best to avoid monkey patching.
On the flip side,
Extending objects like Array.prototype
could lead to complications:
You introduce Array.prototype.flat()
to recursively flatten arrays before September 4, 2018.
Chrome 69 releases JS version of flat
on September 4, 2018.
Your dependencies begin using JS flat
.
Due to the overridden default behavior by your custom method, your application breaks and dependencies no longer operate as expected.
Compared to modifying existing methods through monkey patching:
JavaScript typically follows SOLID's open–closed principle, ensuring that behaviors of existing functions remain consistent.
Therefore, if you opt to monkey patch Array.prototype.find
to support object filters like arr.find({id: 1})
, it should continue to work reliably unless external factors introduce conflicting modifications to the same method.