Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property of a Javascript Class calculated from other properties in same Class

Tags:

This is probably something pretty silly that I'm missing but how do I get the property of a class to automatically re-calculate based on the values of other properties in the same class?

e.g.

function Test() {     this.prop1 = 1;     this.prop2 = 2;     this.prop3 = this.prop1 + this.prop2;  }  tester = new Test();  alert (tester.prop1); // expect 1 alert (tester.prop2); // expect 2 alert (tester.prop3); // expect 3  tester.prop1 += 1;  alert (tester.prop1); // expect 2 alert (tester.prop2); // expect 2 alert (tester.prop3); // expect 4 

or do I need to have prop3 set to be = calcProp3() and then include a function like so:

this.calcProp3 = function() {         var calc = this.prop1 + this.prop2;         return calc;     } 

Thanks all.

like image 599
Duck in Custard Avatar asked Apr 23 '12 14:04

Duck in Custard


People also ask

What are computed properties in JavaScript?

Computed properties allow you to dynamically choose what property in your object gets updated. It's important to give your input element a name attribute. The name attribute that you specify should match the property that you wish to update within the object. Retrieve the name and value from event.

Can I use computed property name?

Computed property names are not allowed either.

What is class property JavaScript?

A JavaScript class is a blueprint for creating objects. A class encapsulates data and functions that manipulate data. Unlike other programming languages such as Java and C#, JavaScript classes are syntactic sugar over the prototypal inheritance. In other words, ES6 classes are just special functions.


2 Answers

or do I need to have prop3 set to be = calcProp3() and then include a function

You have two choices:

  1. Create a property with a getter, which looks like a simple property access when you use it, but is in fact calling a function, or

  2. Do your calcProp3 function, which makes it apparent to the coder using Test that they're calling a function

Option 2 is your only option if you need to support truly obsolete browsers like IE8, since IE8 doesn't support getters.

Using a getter

Here in 2017 you'd probably define it in a class (transpiling if necessary for browsers that don't support ES2015's [aka "ES6"] class):

class Test {    constructor() {      this.prop1 = 1;      this.prop2 = 2;    }    get prop3() {      return this.prop1 + this.prop2;    }  }  const t = new Test();  console.log(t.prop3); // 3  t.prop1 = 2;  console.log(t.prop3); // 4

If you wanted to limit yourself to features of ES5 (spec released December 2009, not supported in IE8), you'd define a getter on Test.prototype, either by using Object.defineProperty (spec, MDN):

function Test() {    this.prop1 = 1;    this.prop2 = 2;  }  Object.defineProperty(Test.prototype, "prop3", {    get: function() {      return this.prop1 + this.prop2;    }  });  var t = new Test();  console.log(t.prop3); // 3  t.prop1 = 2;  console.log(t.prop3); // 4

...or by replacing Test.prototype and using the object initializer syntax for getters (remember to set constructor):

function Test() {    this.prop1 = 1;    this.prop2 = 2;  }  Test.prototype = {    constructor: Test,    get prop3() {      return this.prop1 + this.prop2;    }  };  var t = new Test();  console.log(t.prop3); // 3  t.prop1 = 2;  console.log(t.prop3); // 4

Using a function

Here in 2017, you'd probably define it as a method using class syntax (transpiling if necessary for older browsers):

class Test {    constructor() {      this.prop1 = 1;      this.prop2 = 2;    }    calcProp3() {      return this.prop1 + this.prop2;    }  }  const t = new Test();  console.log(t.calcProp3()); // 3  t.prop1 = 2;  console.log(t.calcProp3()); // 4

If you wanted to stick with ES5 (actually in this case ES3) features to support obsolete browsers, just add a function to the prototype:

function Test() {    this.prop1 = 1;    this.prop2 = 2;  }  Test.prototype.calcProp3 = function calcProp3() {    return this.prop1 + this.prop2;  };  var t = new Test();  console.log(t.calcProp3()); // 3  t.prop1 = 2;  console.log(t.calcProp3()); // 4
like image 122
T.J. Crowder Avatar answered Oct 29 '22 19:10

T.J. Crowder


Javascript now supports a standard way to implement setters and getters via Object.defineProperties().

function Test() {     this.prop1 = 1;     this.prop2 = 2; } Object.defineProperties(Test.prototype, {     prop3: {         get: function test_prop3_get(){ return this.prop1 + this.prop2 },     }, });  tester = new Test();  alert (tester.prop1); //=> 1 alert (tester.prop2); //=> 2 alert (tester.prop3); //=> 3  tester.prop1 += 1;  alert (tester.prop1); //=> 2 alert (tester.prop2); //=> 2 alert (tester.prop3); //=> 4 
like image 29
Kevin Cox Avatar answered Oct 29 '22 19:10

Kevin Cox