Reputation: 17944
Is there a way in which we may update fat arrow function using prototype
?
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet = () => {
alert("Hello, " + this.greeting + " inside");
}
}
Greeter.prototype.greet = () => {
alert("Hello, " + this.greeting + " outside");
}
let greeter = new Greeter("world");
greeter.greet();
// It should alert Hello world outside
// But it is showing Hello world inside
Am i understanding fat arrow syntax incorrectly, and it can not be updated like this, any reference would be helpful?
Here is the Link for Typescript Playground where I was trying
Thanks in Advance!!
Upvotes: 0
Views: 106
Reputation: 164367
To understand what's going on better you should look at the compiled js code:
var _this = this;
var Greeter = (function () {
function Greeter(message) {
var _this = this;
this.greet = function () {
alert("Hello, " + _this.greeting + " inside");
};
this.greeting = message;
}
return Greeter;
}());
Greeter.prototype.greet = function () {
alert("Hello, " + _this.greeting + " outside");
};
There is a greet
function which is added to the prototype, but then when you create a new instance of Greeter
this method is being overridden in the constructor.
It's usually better to have normal class methods:
class Greeter {
// ...
greet() {
alert("Hello, " + this.greeting + " inside");
}
}
Which then compiles into js with the alert
already on the prototype:
var Greeter = (function () {
function Greeter() {
}
Greeter.prototype.greet = function () {
alert("Hello, " + this.greeting + " inside");
};
return Greeter;
}());
If you worry about losing the scope of this
when executing greet
(because you pass it as a callback or something similar) then it's easy to just:
setTimeout(greeter.greet.bind(greeter), 1000);
Or
setTimeout(() => { greeter.greet(); }, 1000);
If you want to do something like this:
class Greeter {
greeting: string;
message: string = "";
constructor(message: string) {
this.greeting = message;
}
greet(){
return "Hello, " + this.greeting + " inside";
}
}
let oldGreet = Greeter.prototype.greet;
Greeter.prototype.greet = function(){
return oldGreet() + " appended outside";
}
It won't work as it will print:
"Hello, undefined inside appended outside"
And that's because the this
isn't the instance of Greeter
, it should be oldGreet.call(this)
:
Greeter.prototype.greet = function(){
return oldGreet.call(this) + " appended outside";
}
Upvotes: 2
Reputation: 6169
When you create a Greeter object. It sets:
this.greet = function () {
alert("Hello, " + _this.greeting + "inside");
};
So it will override what you set in prototype. If you don't write the same greet() function, then it will call what you set in prototype.
Another thing to remember is that when you use arrow function:
Greeter.prototype.greet = () => {
alert("Hello, " + this.greeting + " outside");
}
this.
here is not the object itself, but it belongs to the outer context, that means you can't get this.greeting correctly.
Upvotes: 2