Can someone please explain why defining a prototype function with lambda expression doesn't work? I thought this must be asked before but couldn't find it.
function Book(title, year) {
this.title = title;
this.year = year;
// define a function within the object, which works fine
this.printYear = () => console.log("instance function of an object: " + this.year);
}
this doesn't work
Book.prototype.printTitle2 = () => {
console.log(this.title);
}
and this is fine of course:
Book.prototype.printTitle = function() {
console.log(this);
console.log(this.title);
}
One of the chief features of arrow functions is that they close over the
this
from the context in which they're created; they don't get it based on how they're called like other functions do. So...But your function relies on
this
varying depending on how it's called.This just isn't a use-case for arrow functions. Use a normal function:
Or better yet, use the new
class
syntax:The
Arrow function
would resolve the contextthis
belongs to the scope where the function was defined. I believe you have defined that function inwindow
scope. So thethis
will point towindow
in your function.You can use normal
anonymous function
here. And we have to be careful while using arrow functions.In addition to @t-j-crowder's answer, I wanted to leave a test case (mocha assert) which you can use to visualize which is not working.
Also you can read more about the scope of arrow functions here: You Don't Know JS by Kyle Simpson, who explains
this
in detail.Basically, an arrow function's
this
points to the surrounding context of the current context, which comes in handy if you have enclosing functions. What it does is basically doing thevar self = this;
thing.Or as Kyle says:
You can test it yourself with my gist: https://gist.github.com/jay-bricksoft/96738dd8a48ceb9f517e914b834cc1ee
In my test case this was the output:
EDIT: added example / reference to Kyle Simpson's "You Don't Know ES6" https://github.com/getify/You-Dont-Know-JS/tree/master/es6%20%26%20beyond