Reputation: 307
I im making a Clock class, and it will generate time every second.
class Clock {
constructor(template) {
this._template = template;
this._timer = null;
}
render() {
var date = new Date();
var output = this._template
.replace("h", date.getHours())
.replace("m", date.getMinutes())
.replace("s", date.getSeconds());
console.log(output);
}
start() {
this.render();
this._timer = setInterval(this.render, 1000);
}
}
var clock = new Clock("h:m:s");
clock.start();
At first, it is normal. The output same as what i expect. Then, there will be an error
TypeError: Cannot read property 'replace' of undefined
. It is weird. Why my template
property become undefined?
Upvotes: 0
Views: 63
Reputation: 169338
Since this.render
isn't an arrow function, it will lose its this
binding when used via setInterval
.
Either
render = () => { ... }
), orsetInterval
call:
this._timer = setInterval(this.render.bind(this), 1000);
Upvotes: 3
Reputation: 8515
You are passing this.render
to the setTimeout
function and therefore the this
context is changed. You need to .bind(this)
and everything will work as expected.
class Clock {
constructor(template) {
this._template = template;
this._time = null;
}
render() {
var date = new Date();
var output = this._template
.replace("h", date.getHours())
.replace("m", date.getMinutes())
.replace("s", date.getSeconds());
console.log(output);
}
start() {
this.render();
this._timer = setInterval(this.render.bind(this), 1000); // <-- here
}
}
new Clock('h:m:s').start();
Upvotes: 3