Home > Software design >  how to change a parentClass variable from ChildClass, and make that variable globally for all childs
how to change a parentClass variable from ChildClass, and make that variable globally for all childs

Time:08-12

I have this code:

class ParentClass {
  constructor() {
    /* at the start is 0 because we didn't call it */
    this.previusX = 0;
    this.previusY = 0;
    this.previusZ = 0;
  }

  // if we call a newChildClass() the previus values will not be 0 anymore, but the current x, y, z values.
  setLastPosition() {
    this.previusX = this.x;
    this.previusY = this.y;
    this.previusZ = this.z;
  }
}

class ChildClass extends ParentClass {
  constructor(_obj) {
    super();
    // if there is no obj, then use the previus position (that is the last position)
    // this techically works because we use "??"
    this.x = _obj.x ? ? this.previusX;
    this.y = _obj.y ? ? this.previusY;
    this.z = _obj.z ? ? this.previusZ;

    // if result is not set, then it will be a error, but we will change it (here is work fine, no problem in that)
    this.result = "ERROR";
  }

  print() {
    this.result = `X${this.x} Y${this.y} Z${this.z}`;
    // ❌ this is not working properly, technically
    // if I console.log previusX, previusY, previusZ, it will print the current x, y, z values,
    // but in the next ChildClass it doesn't remember the previus values that are save in parentClass

    // I thinked that if I have for example 10 childrens, the parent be only one
    // and all that children can get the previus values from the parentClass.
    this.setLastPosition();

    return this.result;
  }
}
<!-- see the next code snippet for the example of the problems -->

and when I want to change a parentClass variable from a ChildClass

the parentClass doesn't save the changed variable but gets reset every time.

How can I make the ParentClass share the same variable on all other child?


  • the idea was the ParentClass will be only few (better only 1), but children can be more than 2 (can be also 10 similars).

  • every child has a different object of data

  • but every child have the same data inside the parentClass,
    so if I redefine for example this.previusX all children now have the new value because we changed the parentClass.

  • if a childClass get a null or undefined value in the constructor() then it will try to get the global variable this.previus from parentClass.

  • how to not make reset the value in this.var in ParentClass after creating a new ChildClass? or making that be redefine globally so 0 won't be anymore the returned value but this.x for example.

the only idea I have that can cause the problem is super(); but not sure.
before asking here on StackOverflow I searched a lot but not finding anything (at least with javascript language, maybe in java but I am not familiar with it...)


now here the code with example of errors and what I want, with also comments:

please run the code snippet for understanding the problem, and read also the comments in the html script tag

class ParentClass {
  constructor() {
    /* at the start is 0 because we didn't call it */
    this.previusX = 0;
    this.previusY = 0;
    this.previusZ = 0;
  }

  // if we call a newChildClass() the previus values will not be 0 anymore, but the current x, y, z values.
  setLastPosition() {
    this.previusX = this.x;
    this.previusY = this.y;
    this.previusZ = this.z;
  }
}

class ChildClass extends ParentClass {
  constructor(_obj) {
    super();
    // if there is no obj, then use the previus position (that is the last position)
    // this techically works because we use "??"
    this.x = _obj.x ?? this.previusX;
    this.y = _obj.y ?? this.previusY;
    this.z = _obj.z ?? this.previusZ;

    // if result is not set, then it will be a error, but we will change it (here is work fine, no problem in that)
    this.result = "ERROR";
  }

  print() {
    this.result = `X${this.x} Y${this.y} Z${this.z}`;

    /* ❌ this is not working properly, technically
    if I console.log previusX, previusY, previusZ, it will print the current x, y, z values,
    but in the next ChildClass it doesn't remember the previus values that are save in parentClass

    I thinked that if I have for example 10 childrens, the parent be only one
     and all that children can get the previus values from the parentClass. */

    this.setLastPosition();

    return this.result;
  }
}

test();

function test() {
  // this is correct but in the next examples is not working because I wanted to that if _obj isn't defined it get the previus one.
  console.log(new ChildClass({
    x: 1,
    y: 2,
    z: 3
  }).print());

  // here since z is not defined
  // ❌ it need to be 3, but I don't know why is 0.
  console.log(new ChildClass({
    x: 4,
    y: 5
  }).print());

  // ❌ this need to be "x: 4, y: 5, z: 3" by getting the previus values with "??"
  console.log(new ChildClass({
    x: 3
  }).print());

  // ❌ this need to be "x:3, y:5, z:18"
  console.log(new ChildClass({
    z: 18
  }).print());

  // ✅ if there is all the values then is correct
  console.log(new ChildClass({
    x: 8,
    y: 20,
    z: 30
  }).print());
}
<h1>hello world</h1>






bonus: (don't see this, the problem is in the first code, this is only a bonus if you can, but I will accept your answer also if there is the before answer)

also is there a way to write something like this pseudocode?

let one = new ParentClass();
let two = new ParentClass();

// now the child's class know their parentClass
one.childClass({x:10}).print();
one.childClass({y:30, z:10}).print();
one.childClass({ x: 15, z: 30 }).print();

// the previus values need to be different from the "one".
two.childClass({x:15}).print();
two.childClass({y:25}).print();
two.childClass({ z: 5, x: 30 }).print();

// the values are random, only to test and debugging purposes

this code on top is not the correct syntax code, but maybe I tried to make you understand my wanted logic.
parentClass can share the same variables on all ChildClass, but every ChildClass have it own variables that can't be change... but ParentClass variables can be change by ChildClass and affect all other children.

what I tried to archive this idea? (but is not work)

enter image description here

I tried to console.log the childClass, and I saw that there is Prototype thing there, that has the ParentClass

so I tried to maybe access the ParentClass in the old way with new ChildClass({}).Prototype.ParentClass but not output anything

I am confused, I don't know why is not working, thanks if you help me. enter image description here


so

  1. child class can change a Parent class constructor
  2. if a new child Class is created, the parent class doesn't need to be reset but needs to remember the last changed value.

CodePudding user response:

TLDR:

ParentClass.myVariable = "something";

LONG ANSWER:

I think your problem is in super()
by this I mean that technically when you write this.
you are referring to the ChildClass() not the parent.

remember that when you call super();
javascript literally copies the parentClass and put everything inside the childClass
so when you write this.previusX that value remains always inside the ChildClass

which is great if you think about it, because don't make you have some side effects.


so what it the solution?

you always need to put that super(); OR this. will not work.

but instead of referring to this,
try to refer to the class Name of the parent.

I know you tried to use prototype thing but is not working for you,
but now days with the CLASS keyword, this became a lot easier with this syntax sugar

so just write something like this:

ParentClass.myVariable = "something";

like this photo:

enter image description here enter image description here

here the result of console:

enter image description here

you see works great, there is no 0 there.

class ParentClass {
  constructor() {
    this.previusX = 0;
    this.previusY = 0;
    this.previusZ = 0;
  }
}

class ChildClass extends ParentClass {
  constructor(_obj) {
    super();
    this.x = _obj.x ?? ParentClass.previusX;
    this.y = _obj.y ?? ParentClass.previusY;
    this.z = _obj.z ?? ParentClass.previusZ;

    this.result = "ERROR";
  }

  print() {
    this.result = `X${this.x} Y${this.y} Z${this.z}`;
    this.setLastPosition();

    return this.result;
  }

  setLastPosition() {
    ParentClass.previusX = this.x;
    ParentClass.previusY = this.y;
    ParentClass.previusZ = this.z;
  }
}

test();

function test() {
  // this is correct but in the next examples is not working because I wanted to that if _obj isn't defined it get the previus one.
  console.log(new ChildClass({
    x: 1,
    y: 2,
    z: 3
  }).print());

  // here since z is not defined
  // ❌ it need to be 3, but I don't know why is 0.
  console.log(new ChildClass({
    x: 4,
    y: 5
  }).print());

  // ❌ this need to be "x: 4, y: 5, z: 3" by getting the previus values with "??"
  console.log(new ChildClass({
    x: 3
  }).print());

  // ❌ this need to be "x:3, y:5, z:18"
  console.log(new ChildClass({
    z: 18
  }).print());

  // ✅ if there is all the values then is correct
  console.log(new ChildClass({
    x: 8,
    y: 20,
    z: 30
  }).print());
}


⚠️ but there is a extra bug!

if setLastPosition() method don't get run at the start,
then ParentClass previous var it will be undefined,
and it won't get the 0 value.

so why before was working, and for me seems to work?

yes, in most of the cases it will work,
but if in the first ChildClass you didn't define the x, y, z then this will happen

example: new ChildClass({ x: 1, y: 2 } now all the other next ChildClasses without defined z will be undefined

class ParentClass {
  constructor() {
    this.previusX = 0;
    this.previusY = 0;
    this.previusZ = 0;
  }
}

class ChildClass extends ParentClass {
  constructor(_obj) {
    super();
    this.x = _obj.x ?? ParentClass.previusX;
    this.y = _obj.y ?? ParentClass.previusY;
    this.z = _obj.z ?? ParentClass.previusZ;

    this.result = "ERROR";
  }

  print() {
    this.result = `X${this.x} Y${this.y} Z${this.z}`;
    this.setLastPosition();

    return this.result;
  }

  setLastPosition() {
    ParentClass.previusX = this.x;
    ParentClass.previusY = this.y;
    ParentClass.previusZ = this.z;
  }
}

test();

function test() {
  // this is correct but in the next examples is not working because I wanted to that if _obj isn't defined it get the previus one.
  console.log(new ChildClass({
    x: 1,
    y: 2
  }).print());

  // here since z is not defined
  // ❌ it need to be 3, but I don't know why is 0.
  console.log(new ChildClass({
    x: 4,
    y: 5
  }).print());

  // ❌ this need to be "x: 4, y: 5, z: 3" by getting the previus values with "??"
  console.log(new ChildClass({
    x: 3
  }).print());

  // ❌ this need to be "x:3, y:5, z:18"
  console.log(new ChildClass({
    z: 18
  }).print());

  // ✅ if there is all the values then is correct
  console.log(new ChildClass({
    x: 8,
    y: 20,
    z: 30
  }).print());
}

enter image description here

quick solution can be:

using another ?? that check if is null or undefined,
if so then put 0 also that.

enter image description here

this.x = _obj.x ?? ParentClass.previusX ?? 0;
this.y = _obj.y ?? ParentClass.previusY ?? 0;
this.z = _obj.z ?? ParentClass.previusZ ?? 0;

now instead of telling you undefined it will tell you 0

enter image description here

class ParentClass {
  constructor() {
    this.previusX = 0;
    this.previusY = 0;
    this.previusZ = 0;
  }
}

class ChildClass extends ParentClass {
  constructor(_obj) {
    super();
    this.x = _obj.x ?? ParentClass.previusX ?? 0;
    this.y = _obj.y ?? ParentClass.previusY ?? 0;
    this.z = _obj.z ?? ParentClass.previusZ ?? 0;

    this.result = "ERROR";
  }

  print() {
    this.result = `X${this.x} Y${this.y} Z${this.z}`;
    this.setLastPosition();

    return this.result;
  }

  setLastPosition() {
    ParentClass.previusX = this.x;
    ParentClass.previusY = this.y;
    ParentClass.previusZ = this.z;
  }
}

test();

function test() {
  // this is correct but in the next examples is not working because I wanted to that if _obj isn't defined it get the previus one.
  console.log(new ChildClass({
    x: 1,
    y: 2
  }).print());

  // here since z is not defined
  // ❌ it need to be 3, but I don't know why is 0.
  console.log(new ChildClass({
    x: 4,
    y: 5
  }).print());

  // ❌ this need to be "x: 4, y: 5, z: 3" by getting the previus values with "??"
  console.log(new ChildClass({
    x: 3
  }).print());

  // ❌ this need to be "x:3, y:5, z:18"
  console.log(new ChildClass({
    z: 18
  }).print());

  // ✅ if there is all the values then is correct
  console.log(new ChildClass({
    x: 8,
    y: 20,
    z: 30
  }).print());
}

now I think that the constructor that is inside ParentClass() isn't necessary anymore.

because also with that it will be always wrong (always 0), but we can manually create it and access it by parentClass.previusX

since super(); is always necessary, but it takes a unnecessary variable that can maybe cause you some bugs. enter image description here


so that it is, here is the correct code:

class ParentClass {
  //not necessary for now.
}

class ChildClass extends ParentClass {
  constructor(_obj) {
    super();
    this.x = _obj.x ?? ParentClass.previusX ?? 0;
    this.y = _obj.y ?? ParentClass.previusY ?? 0;
    this.z = _obj.z ?? ParentClass.previusZ ?? 0;

    this.result = "ERROR";
  }

  print() {
    this.result = `X${this.x} Y${this.y} Z${this.z}`;
    this.setLastPosition();

    return this.result;
  }

  setLastPosition() {
    ParentClass.previusX = this.x;
    ParentClass.previusY = this.y;
    ParentClass.previusZ = this.z;
  }
}

test();

function test() {
  console.log(new ChildClass({
    x: 1,
    y: 2
  }).print());

  console.log(new ChildClass({
    x: 4,
    y: 5
  }).print());

  console.log(new ChildClass({
    x: 3
  }).print());

  console.log(new ChildClass({
    z: 18
  }).print());

  console.log(new ChildClass({
    x: 8,
    y: 20,
    z: 30
  }).print());
}

  • Related