I'm trying to move from procedural to object-oriented JavaScript and I'm coming up against an issue I'm sure there's an answer to, but I can't work it out.
Currently, each of my methods checks the state of a property, and then performs an action based on that state. What I'd rather do is update the state and those methods execute as a result of the state change. Is that possible, or am I missing the point?
Here's what I have currently:
class ClassExample {
constructor({state = false} = {}) {
this.state = state;
...
}
aMethod() {
if(this.state) {
//Do something
this.state = false;
} else {
//Do something else
this.state = true;
}
}
bMethod() {
if(this.state) {
//Do something
this.state = false;
} else {
//Do something else
this.state = true;
}
}
}
And:
const myObject = new ClassExample();
myObject.aMethod();
myObject.bMethod();
Given both methods are checking the same property, it's resulting in a lot of redundant if
statements. Is there a better way to organise this class
to achieve the same result?
I'd suggest you use an event driven system based on the EventEmitter()
object built into node.js.
To keep track of state changes, you can define a setter for your state variables so that any time someone sets a new state, then your setter function will get called and it can then trigger an event that indicates the state changed. Meanwhile, anyone in your object out outside your object can register an event listener for state changes.
Here's a short example:
const EventEmitter = require('events');
class ClassExample extends EventEmitter {
constructor(state = 0) {
super();
// declare private state variable
let internalState = state;
// define setter and getter for private state variable
Object.defineProperty(this, "state", {
get: function() {
return internalState;
},
set: function(val) {
if (internalState !== val) {
internalState = val;
// send out notification
this.emit("stateChanged", val);
}
}
});
}
}
let e = new ClassExample(1);
console.log(e.state);
e.on("stateChanged", function(newVal) {
console.log("state has changed to ", newVal);
});
e.state = 3;
console.log(e.state);