Reputation: 368
I am trying to solve some JavaScript questions about prototype (and maybe closure). I am very new to this concept.
I need to create a MyNumber prototype, then add increment function which will return a number that is incremented by 1. Here I will create multiple instances of the prototype and every instance will keep track of its own value separately.
Here is my logically broken code:
function MyNumber(num) {
this.num = num;
}
MyNumber.prototype.increment = function() {
return function() {
++this.num
}
}
After this example, I need to create a Clock prototype, which will increment by one every second.
Upvotes: 0
Views: 41
Reputation: 50974
While you're using function constructors, I would suggest you use ES6's classes. It will allow you to write more readable and maintainable code. Your MyNumber
function can be made into a class
by creating your own constructor()
and increment()
methods. The increment()
method is in charge of incrementing the number and returning the new number.
Since you need a clock, you could also make an additional Clock
class. This extends
the MyNumber
class, which allows Clock
to access the properties and methods declared in the MyNumber
class. Since a clock needs to have an internal counter we can extend MyNumber
which provides this counting functionality for us.
The Clock
class has a constructor which calls the MyNumber
's constructor by doing a super()
call. This initializes what this.num
will be in our Clock
class. The constructor also accepts additional arguments such as an action, which is a function that gets executed every time the clock "ticks" and a speed
for how fast the clock should "tick".
The Clock
class also implements a begin()
method, which uses setInterval()
to repeatedly execute the passed through arrow function. The arrow function is executed every x m/s (based on the this.speed
property). Every time the arrow function is executed, it increments the clocks internal counter (using the .increment()
provided by the extended MyNumber
class). It also executes the action
function passed through the constructor initially.
You can then create an instance of your Clock
class and pass through the required arguments to the constructor like so:
class MyNumber {
constructor(num) {
this.num = num;
}
increment() {
return ++this.num;
}
}
class Clock extends MyNumber {
constructor(beginTime, action, speed=1) { // default speed to `1`
super(beginTime);
this.act = action;
this.speed = speed; // in seconds
}
begin() {
this.act(this.num); // call once before looping
setInterval(() => { // executes every `this.speed` seconds
const new_time = this.increment(); // increment the time and get the new time
this.act(new_time); // execute the action
}, this.speed*1000);
}
}
const clock = new Clock(3, t => console.log(`Tick tock, the time is ${t}`));
clock.begin();
Upvotes: 1
Reputation: 13678
The main problem I see here is that rather than your increment
method simply incrementing this.num
, it returns a function
that increments this.num
. In the example below, I rewrote it to simply do the incrementing itself. Also in the example we make sure we create new instances using the new
operator, so that the JS engine knows we're creating a new instance of an object:
function MyNumber(num) {
this.num = num;
}
MyNumber.prototype.increment = function() {
++this.num;
}
let myNumA = new MyNumber(10);
let myNumB = new MyNumber(100);
console.log(myNumA.num); // 10
console.log(myNumB.num); // 100
myNumB.increment();
console.log(myNumA.num); // 10
console.log(myNumB.num); // 101
Upvotes: 1