4

Is it possible to give an object a dynamic property, or rather give an object property a dynamic value? For example:

var obj = {
    a: 0,
    b: 5,
    c: //should always be a+b
}

Obviously I could use a method c=function(){return a+b}, but then I would always need to call c as a method using braces (obj.c() instead of obj.c). This wouldn't really be a problem, but I belive it has to work somehow, since the build in length property also is a property and not a function. This property changes dynamically with the object and isn't a function...

var str = "hello world";
console.log(str.length); //11
str = "hello stack overflow";
console.log(str.length); //20

The property value changes without it beeing updated...

I hope you can help me :)

Anton Ballmaier
  • 876
  • 9
  • 25
  • 2
    You're looking for ES5 getters. But `.length` is not dynamic; strings are immutable. – SLaks Jan 09 '17 at 16:30
  • As @SLaks mentions, it is important to note that `String#length` is not a dynamic property because a string's internal value cannot be changed. – Phylogenesis Jan 09 '17 at 16:34
  • 1
    Your string example doesn't prove your point. You are creating a second new string with a different length. The equivalent with your object would be: `var obj = {c: 21}; console.log(obj.c); obj = {c: 42}; console.log(obj.c);`. See, `c` also changed "dynamically" ;) – Felix Kling Jan 09 '17 at 16:44

3 Answers3

4

Define a getter when creating the object, or add it later using Object#defineProperty:

var obj = {
  a: 0,
  b: 5,
  get c() { // assign it at object creation
    return this.a + this.b;
  }
};

console.log(obj.c);

// add it to existing object
Object.defineProperty(obj, 'd', {
  get: function() {
    return this.a + this.b + this.c;
  }
});


console.log(obj.d);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
1

Beside getters, you could use an ES6 feature, Proxy

The Proxy object is used to define custom behavior for fundamental operations (e.g. property lookup, assignment, enumeration, function invocation, etc).

var obj = {
        a: 0,
        b: 5,
    },
    p = new Proxy(obj, {
        get: function(target, prop) {
            return prop === 'c' ? target.a + target.b : target[prop];
        }
    });
   
console.log(p.c); // 5
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

You can use a getter:

var o = {
   a : 0; 
   b : 1;
   get c () {return this.a + this.b;}

}
kemiller2002
  • 113,795
  • 27
  • 197
  • 251