1

I want to define one property of an object in terms of another, like this:

let obj = {
  prop1: some value,
  prop2: some expression in terms of prop1 (e.g. prop1 * 2)
}

So whenever I refer to prop2 in my code, that expression that I initialised it as will be evaluated. Is this possible?

Ivan
  • 131
  • 6
  • This is a particularly clearly asked version of this question. I'm surprised not to have managed to find a good dupetarget for it. Giving up now. Anyway, even if someone finds one: Well-asked question! – T.J. Crowder Dec 11 '19 at 18:54
  • @T.J.Crowder we got a standard canonical one… – Bergi Dec 11 '19 at 20:17
  • @Bergi - I don't see that [that question](https://stackoverflow.com/questions/4616202/self-references-in-object-literals-initializers) applies at all. – T.J. Crowder Dec 12 '19 at 07:38

2 Answers2

1

You can do that with an accessor property with a getter function:

let obj = {
  prop1: 21,
  get prop2() {
    return this.prop1 * 2;
  }
};

console.log(obj.prop1); // 21
console.log(obj.prop2); // 42

If you like, you can also define a setter for it:

let obj = {
  prop1: 21,
  get prop2() {
    return this.prop1 * 2;
  },
  set prop2(value) {
    this.prop1 = value / 2;
  }
};

console.log(obj.prop1); // 21
console.log(obj.prop2); // 42

obj.prop2 = 8;
console.log(obj.prop1); // 4
console.log(obj.prop2); // 8

More on MDN: get, set.

Finally, you can do it in class definitions, too:

class Example {
    constructor(prop1) {
        this.prop1 = prop1;
    }
    get prop2() {
      return this.prop1 * 2;
    }
    set prop2(value) {
      this.prop1 = value / 2;
    }
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

You can make prop2 be a function that fetches the value of prop1, performs some logic and returns the result. This way (if you want) you can even have the output of prop2 to be up-to-date with the changes in prop1.

Example: (run it below)

let obj = {
  prop1: 45,
  prop2 : function() {
    return this.prop1 * 3;
  }
};



console.log( obj.prop2() );
Ivan86
  • 5,695
  • 2
  • 14
  • 30