skip to Main Content

I am trying to develop a more object oriented approach to my programming but have run into a problem. I thought it would be useful to group related properties in an object together with methods that operate on the properties.

An example of this would be an object holding some properties with strings as values together with a method that can iterate over all of the (non-method) properties changing them to uppercase.

const myObj = {
  prop1: "one",
  prop2: "two",
  myMethod: function() {
    Object.keys(this).forEach(prop => {
      if (typeof this[prop] !== "function"){
        this[prop] = this[prop].toUpperCase();
      }
    });
  },
}

console.log(myObj.prop1, myObj.prop2);
myObj.myMethod();
console.log(myObj.prop1, myObj.prop2);

I would be happy with this if it was not for the need to have a conditional clause, if (typeof this[prop] !== "function"){...}, in order to prevent the method working on methods as well as properties. Although the conditional clause does work in this case you might have a case where you have some methods which you want other methods to operate on and there is a distinction (for you) between the methods you want to be operated on and those that do the operating.

One way around using the conditional would be to put the properties you want to be acted on inside another object but then that means that when you use them you have a more complicated way of referencing them:

const myObj = {
  props: {
    prop1: "one",
    prop2: "two",
  }
  myMethod: function() { ... }
    });
  },
}

Now I would have to reference the properties as myObj.props.prop1 instead of myObj.prop1 which looks much better to me.

I was wondering whether there is some common satisfactory way of addressing this issue and what other people think about it.

2

Answers


  1. You could always define your method as non-enumerable. Then, methods that act on properties through the Object.keys method will not affect it.

    const myObj = {
      prop1: "one",
      prop2: "two"
    }
    
    Object.defineProperty(myObj, 'myMethod', {
      enumerable: false,
      value: () => Object.keys(myObj).forEach(prop => myObj[prop] = myObj[prop].toUpperCase())
    });
    
    console.log(Object.keys(myObj));
    
    console.log(myObj.prop1, myObj.prop2);
    myObj.myMethod();
    console.log(myObj.prop1, myObj.prop2);

    References

    Login or Signup to reply.
  2. You can simply set the enumerable property to false:

    const myObj = {
      prop1: "one",
      prop2: "two",
      myMethod: function() {
        Object.keys(this).forEach(prop => {
          console.log (prop,  this[prop], typeof this[prop] );
        });
      },
    }
    
    // change enumerable property :
    Object.defineProperty(myObj, 'myMethod', {enumerable: false} );
    
     
    myObj.myMethod();
     
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search