构造函数中的复合属性

时间:2014-02-11 19:01:05

标签: javascript

我想构建一个如下所示的对象数组:

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

并添加以下复合属性:

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

使用相同的方法添加属性:

  • groupB.propertyC - > groupB.propertyA + groupB.propertyB
  • totals.propertyA - > groupA.propertyA + groupB.propertyA
  • totals.propertyB - > groupA.propertyB + groupB.propertyB
  • totals.propertyC - > groupA.propertyC + groupB.propertyC

我通过将所有这些代码放在一个函数中来完成所有这些工作,因此它将someObject添加到数组中。

但后来我开始认为不需要为每个对象创建只读复合属性,而且可能是原型。

这有意义吗?是否可能,如果是这样的话:怎么样?

2 个答案:

答案 0 :(得分:3)

可以做到。您只需要确保groupA和groupB从具有复合属性的对象继承。

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

答案 1 :(得分:0)

我不知道你的问题是否理解得很清楚;但是一般来说,如果您想要在特定类型的所有实例中共享成员,那么您应该将它们放入构造函数的原型中。

在你的例子中,你使用的是对象文字,这样做不容易,除非你扩展了Object构造函数的原型,我不推荐这样做。

做这样的事情怎么样:

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 }
 });