Reputation: 123
I am trying to make this code works properly:
class Reminder {
constructor(text) {
this.text = text;
}
remindMe(delay) {
setTimeout(function() {
console.log(`Your reminder after ${delay} seconds is: ${this.text}`);
}, delay * 1000);
}
}
//shows Reminder {text: "Hello World"}
const example = new Reminder("Hello world");
//shows undefined
console.log(example);
// shows "Your reminder after 3 seconds is: undefined"
console.log(example.remindMe(3));
I have been without working with classes a lot of time, and I know is undefined
because the method remindMe
doesnt have access to the constructor, because it doesnt have a getter. But I have tried to create a getter and it didnt leave me to call it from the method remindMe
, I tried to do something like this:
remindMe(delay) {
setTimeout(function () {
console.log(`Your reminder after ${delay} seconds is: ${getText()});
}, delay * 1000);
}
Any idea about where is the mistake? Thanks.
Upvotes: 0
Views: 775
Reputation: 63524
example
is being logged in your code (as you can see from the snippet). It logs:
{
"text": "Hello world"
}
remindMe
doesn't explicitly return anything so defaults to undefined
(that's the first undefined
in your output). (Note: since remindMe
is also a function containing a timeout it still wouldn't work because you're logging immediately, and the function only completes after three seconds. Plus it contains its own console.log
so there's no need to log the result of calling the function anyway.)
this
won't work as you want it to in that setTimeout
because the context has changed. Use an arrow function instead - they have no this
of their own and "borrow" this
from its outer lexical environment.
class Reminder {
constructor(text) {
this.text = text;
}
remindMe(delay) {
setTimeout(() => {
console.log(`Your reminder after ${delay} seconds is: ${this.text}`);
}, delay * 1000);
}
}
const example = new Reminder("Hello world");
console.log(example);
example.remindMe(3);
Upvotes: 1
Reputation: 877
It is because you're using a function
as callback in your interval, redefining the context, therefore the value of this
.
Use arrow function
instead:
remindMe(delay) {
setTimeout(() => {
console.log(`Your reminder after ${delay} seconds is: ${this.text}`);
}, delay * 1000);
}
The other undefined
comes from the fact that you're printing the return value of remindMe
but it doesn't have any return
keyword, therefore undefined
is returned.
Upvotes: 1
Reputation: 17149
The remindMe
method is undefined
because it doesn't return
anything, this.text
is undefined too, because this
here refers to window
, you need to bind
this with Reminder
Object.
class Reminder {
constructor(text) {
this.text = text;
}
remindMe(delay) {
setTimeout(function() {
console.log(`Your reminder after ${delay} seconds is: ${this.text}`);
}.bind(this), delay * 1000);
}
}
//shows Reminder {text: "Hello World"}
const example = new Reminder("Hello world");
//shows undefined
console.log(example);
// shows "Your reminder after 3 seconds is: undefined"
console.log(example.remindMe(3));
Upvotes: 1