I am struggling to implement composition in ES6 classes! I am trying to understand a lot of things at once and have maybe made a stupid error.
I would like to avoid inheritance using extend
and super
for now, and have found this nice example of composition that seems to show what I am after:
class EmployeeTaxData {
constructor(ssn, salary) {
this.ssn = ssn;
this.salary = salary;
}
// ...
}
class Employee {
constructor(name, email) {
this.name = name;
this.email = email;
}
setTaxData(ssn, salary) {
this.taxData = new EmployeeTaxData(ssn, salary);
}
// ...
}
In regard to the code below, I would like to use the most simple and eloquent way to make the spin() method available for the objects created by the Hero
class so it is using a shared prototype. I would like to share this method with other objects that will need it too.
Unfortunately I can't make my code work as the this.angle
is not referring to to the Hero
class that it needs to, but the Spinner
class?
class Spinner {
constructor(direction){
this.direction = direction;
}
spin(direction) {
switch (direction) {
case 'left':
this.angle -= 1;
break;
case 'right':
this.angle += 1;
break;
// no default
}
}
}
class Hero {
constructor(xPosition, yPosition) {
this.description = 'hero';
this.width = 25;
this.height = 50;
this.xPosition = xPosition;
this.yPosition = yPosition;
this.angle = 0;
this.color = 'red';
this.spin = new Spinner();
}
spin() {
this.spin.spin();
}
}
const heroClass = new Hero(100, 200);
console.log(heroClass.angle); // result is 0
heroClass.spin.spin('left');
console.log(heroClass.angle); // result is STILL 0, it didn't work
...the this.angle is not referring to to the Hero class that it needs to, but the Spinner class?
As it should. When you're inside the spinner class, then this
refers to a spinner object, which also means this.angle
inside the spinner class refers to an angle property of a spinner object.
You'll probably want spinner to return a new angle value, then the hero object that uses spinner should save the returned new angle value.
class Spinner {
constructor(direction){
this.direction = direction;
}
spin(direction, angle) {
switch (direction) {
case 'left':
angle -= 1;
break;
case 'right':
angle += 1;
break;
// no default
}
return angle;
}
}
class Hero {
constructor(xPosition, yPosition) {
this.description = 'hero';
this.width = 25;
this.height = 50;
this.xPosition = xPosition;
this.yPosition = yPosition;
this.angle = 0;
this.color = 'red';
this.spinner = new Spinner();
}
spin(direction) {
this.angle = this.spinner.spin(direction, this.angle);
}
}
const heroClass = new Hero(100, 200);
console.log(heroClass.angle); // result is 0
heroClass.spin('left');
console.log(heroClass.angle); // result is -1
I had to make a few other small changes for this to work. For example, you had a data property named "spin" this.spin = new Spinner
as well as a method named spin spin() {
. They were overriding one another.