it's my code
"use strict";
class Employee {
constructor(firstName, lastName, age, salary, gender) {
this._firstName = firstName;
this._lastName = lastName;
this._age = age;
this._salary = salary;
Object.defineProperty(this, "_gender", {
enumerable: true,
configurable: true,
set(value) {
if(typeof value !== "boolean"){
throw "Wrong type of data.";
}else{
this._newGender = value;
}
},
get() {
return this._newGender;
}
});
this._gender = gender;
this._retirementYears = 0;
}
retirement() {
if (this._gender === true) {
return this._retirementYears = 65 - this._age;
} else if (this._gender === false) {
return this._retirementYears = 60 - this._age;
} else {
console.error("Invalid gender.");
}
}
}
class Teacher extends Employee {
constructor(firstName, lastName, age, salary, gender, subject, yearsOfExperience) {
super(firstName, lastName, age, salary, gender);
this._subject = subject;
this._yearsOfExperience = yearsOfExperience;
}
}
const mathTeacher = new Teacher("John", "Smith", 35, 6000, true, "Math", 5);
console.log(mathTeacher);
After console.log(mathTeacher) I get two properties relating to gender (_gender and _newGender). I want to get only one property called _gender and I have no idea how to do it. I tried to assign assign value to this._gender but it doesn't work due to "Maximum call stack size exceeded" error
There are several solution but what made the question interesting, whether cloning of an class instance works for each approach.
To clone an class instance we could use:
As turned out only the last approach works with cloning when the property is defined in the prototype. The provided cloning doesn't call the constructor. And calling the constructor is problematic since the arguments are unknown at the time of cloning.
But I would say that we need some
clone()method in a class to make cloning more flexible. So the cloning failures seen here aren't critical imho.So let's start it rolling:
You can use a private property (CLONING FAILED !!!):
Or make
_newGendernot enumerable (CLONING FAILED !!!):Actually you could create some utility for this and keep the real value in its scope (CLONING FAILED !!!):
If you want to use the getter/setter in the prototype (like a JS class would do (but the property isn't enumerable)) use a symbol to keep the real value (symbol properties aren't enumerable):
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
(CLONING OK):