Madhu Ranjan Madhu Ranjan - 2 months ago 6
TypeScript Question

How to update fat arrow function using prototype?

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!!

Answer

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);

Edit

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";
}

(code in playground)

Comments