Search code examples
javascriptcomputer-sciencestandardsanti-patternsstandards-compliance

What is the jargon or area of study for this type of code (non-compliant, non-conforming)?


What is the technical jargon for a module/library that's considered bad because it strays from or changes standard behavior (especially implicitly)?

For example, if I have module.js with the following contents...

Object.assign = (x, y) => {
  // Do a deep copy instead...
}

...consumers of the module could end up confused when Object.assign doesn't work like usual.

Also, what's the area(s) of study that this falls under? I want to know what to search so I can read about it.

EDIT: Changed to a better example


Solution

  • It's called monkey patching.

    https://en.wikipedia.org/wiki/Monkey_patch

    Your example of the monkey patching is malicious and nobody should do that. Because it will break almost any code that uses Object.assign.

    About this particular example you could do a variant:

    {
      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() looks better and safer and there's less typing, but unfortunately it will fail when JS would add the same method in the future (see below)...

    So with this Object.assign case we don't have a 100% bulletproof solution unfortunately...

    The best approach would be just:

    Object.assign(a, structuredClone(b));
    

    But in general the answer whether the monkey patching is bad is opiniated unfortunately.

    I love monkey patching BUT:

    • monkey patching in your project is OK
    • you have to keep the default behavior, just add extra functionality
    • if you deliver code for using by others (a framework, a module, a library) it's NO

    On the other hand

    Extending for example Array.prototype could be a bad idea:

    • you add Array.prototype.flat() to flatten an array recursively before 2018-09-04.

    • in 2018-09-04 Chrome 69 Released which adds the JS version of flat.

    • you upgrade your dependencies which started using JS flat.

    • your app breaks because you override the default behavior of the JS flat (1 level deep) and your dependencies stop working as expected.

    Compared to monkey patching existing methods:

    I believe JS follows the SOLID's open–closed principle so no behavior of existing functions would ever change.

    So if you monkey patch Array.prototype.find for example to work with object filters like arr.find({id: 1}) I think it will work forever unless you add some bad 3rd party code with monkey patching this method too.