0

I need a couple of methods to manage Objects like deep cloning (coloning an object and cloning all its nested objects), a deep object assing, etc.

Is it a good idea or a bad practice to add these methods to the Object proptotype?

In angular we have a designated polyfills.ts file and I can add them there, but should I?

The other option iIthought is to create a Utility class, maybe public class with static method that has these methods.

I added the folowing code to the angular polyfills.ts

declare global {
  interface Object {
    $deepObjectAssign(target: { [key: string]: any }, source: { [key: string]: any },  cleanObject?: boolean): { [key: string]: any };
  }
}

if (!Object.prototype['$deepObjectAssign']) {

  Object.defineProperty(Object.prototype, '$deepObjectAssign', {
    value: (target: { [key: string]: any }, source: { [key: string]: any }, cleanObject?: boolean): { [key: string]: any } => {
      if (cleanObject) {
        for (const key of Object.keys(target)) {
          if (!source[key] === undefined) {
            delete target[key]
          }
        }
      }
      for (const key of Object.keys(source)) {
        if (!target[key]) target[key] = source[key];
        if (source[key] instanceof Object) Object.assign(source[key], Object.$deepObjectAssign(target[key], source[key]))
      }
      Object.assign(target || {}, source)
      return target
    }
  })
}

My other option is to have a utily class

export class ObjectsUtilities {

   public static deepObjectAssign (target: { [key: string]: any }, source: { [key: string]: any }, cleanObject?: boolean): { [key: string]: any } {
      if (cleanObject) {
        for (const key of Object.keys(target)) {
          if (!source[key] === undefined) {
            delete target[key]
          }
        }
      }
      for (const key of Object.keys(source)) {
        if (!target[key]) target[key] = source[key];
        if (source[key] instanceof Object) Object.assign(source[key], Object.$deepObjectAssign(target[key], source[key]))
      }
      Object.assign(target || {}, source)
      return target
    }
  })
}
Juan Luces
  • 29
  • 7
  • Is there a standard or a standard proposal that you're trying to implement? If not, then it's not a [polyfill](https://remysharp.com/2010/10/08/what-is-a-polyfill). – skink Dec 22 '22 at 12:59

1 Answers1

0

For reference on the discussion on extending builtin JavaScript types you can look here. To me it is unclear if it is a good idea or not, but in your exact case I would just define a utility function. No need for any class:

export function deepObjectAssign (target: { [key: string]: any }, source: { [key: string]: any }, cleanObject?: boolean): { [key: string]: any } {
      if (cleanObject) {
        for (const key of Object.keys(target)) {
          if (!source[key] === undefined) {
            delete target[key]
          }
        }
      }
      for (const key of Object.keys(source)) {
        if (!target[key]) target[key] = source[key];
        if (source[key] instanceof Object) Object.assign(source[key], Object.$deepObjectAssign(target[key], source[key]))
      }
      Object.assign(target || {}, source)
      return target
    }
  })
}
Garuno
  • 1,935
  • 1
  • 9
  • 20