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 examplethis.previusX
all children now have the new value because we changed the parentClass.if a
childClass
get a null or undefined value in theconstructor()
then it will try to get the global variablethis.previus
fromparentClass
.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 butthis.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 allChildClass
, but everyChildClass
have it own variables that can't be change... butParentClass
variables can be change byChildClass
and affect all other children.
what I tried to archive this idea? (but is not work)
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.
so
- child class can change a Parent class constructor
- 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:
here the result of console:
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 ChildClass
es 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());
}
quick solution can be:
using another ??
that check if is null
or undefined
,
if so then put 0
also that.
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
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.
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());
}