carlsb3rg
carlsb3rg

Reputation: 772

Composite properties in constructor

I want to build an array of objects which look like this:

var someObject = {
  id,
  groupA {
    propertyA: 0,
    propertyB: 0,
  },
  groupB {
    propertyA: 0,
    propertyB: 0
  totals {}
 }

And add the following composite property:

Object.defineProperty(someObject.groupA, "propertyC", 
  {
    get: function() { 
      return someObject.groupA.propertyA + someObject.groupA.propertyB;
    }
  });

And use the same method to add the properties:

I got all this working by putting all this code in a function so it added someObject to an array.

But then I got to thinking that the read-only composite properties shouldn't need to be created for each object and could probably be in a prototype.

Does this make sense? And is it possible, and if so: how?

Upvotes: 0

Views: 70

Answers (2)

Tibos
Tibos

Reputation: 27823

It can be done. You just need to make sure that groupA and groupB inherit from an object which has the composite property.

var proto = {};
Object.defineProperty(proto, 'propertyC', {
  get : function() { return this.propertyA + this.propertyB; }
});

var someObj = {
  id : '1',
  groupA : Object.create(proto, {
    propertyA : { value : 1 }, propertyB : { value : 2 }
  }),
  groupB : Object.create(proto, {
    propertyA : { value : 3 }, propertyB : { value : 4 }
  }),
  totals : Object.create(proto, {
    propertyA : { get : function() { return someObj.groupA.propertyA + someObj.groupB.propertyA; } },
    propertyB : { get : function() { return someObj.groupA.propertyB + someObj.groupB.propertyB; } }
  })
}

// Usage: 
console.log(someObj.groupA.propertyC); // 3
console.log(someObj.groupB.propertyC); // 7
console.log(someObj.totals.propertyC); // 10

Upvotes: 3

ppoliani
ppoliani

Reputation: 4906

I don't know if understood well your question; but in general when you have members that you want to share across all the instances of a particular type then you should put them into the prototype of the constructor.

In your example, you're using object literal, which doesn't make it easy to do so, unless you extend the prototype of the Object constructor, which I would not recommend.

How about doing something like this:

var SomeType = function(){
   this.id = 0;
   this.groupA = {
     propertyA: 0,
     propertyB: 0
   };

   this.groupA = {
     propertyA: 0,
     propertyB: 0
   };

   this.total = {};
}

SomeType.prototype = {
   constructor: SomeType
}

Object.defineProperty(SomeType.prototype, 'propertyC', {
    get: function(){ return this.groupA.propertyA + this.groupA.propertyB }
 });

Upvotes: 0

Related Questions