Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force typescript to put methods on the instance not the prototype

Tags:

typescript

Is it possible to force typescript to put methods on the instance not the prototype. I ask this because I frequently have "this" scope issues which having methods on the prototype causes issues with.

Edit


For example in the output from the ts it seems inconsistent, I keeps the FooAlert in the FooViewModel function but the method openFooAlertDialogueAdd in the prototype

Js

var FooViewModel = (function () {
    function FooViewModel (json) {
        this.Foolert = ko.observable();

    }
    FooViewModel.prototype.openFooAlertDialogueAdd = function () {
        this.FooAlert = something;
    };

Ts

class FooViewModel{
     FooAlert = KnockoutObservableAny

      constructor(){
         this.FooAlert = ko.observable();
       }
     openFooAlertDialogueAdd() {
        this.FooAlert = something;
    };

}
like image 424
FutuToad Avatar asked Mar 11 '13 09:03

FutuToad


2 Answers

If you're having scope issues I feel bad for you son, I've got 99 problems but this ain't one!

Steve's answers show the correct way to define class methods, methods that will be exposed on each instance. However, if you're encountering scope issues, this is probably due to the fact you're calling those methods from another context.

For example, if you're using Knockout and you bind one of those methods to a click binding, Knockout will override the scope to the current scope of the binding, NOT the scope you have defined the method on.

There are two options to prevent this loss of scope.

Firstly you can define your methods in the constructor, to expose them on the instance instead of on the prototype.

Like:

class Greeter {
    greet:() => string;
    greeting: string;

    constructor(message: string) {
        this.greeting = message;
        this.greet = () => {
            return "Hello, " + this.greeting;
        }
    }

Secondly, you could use the => syntax to scope your class methods.

Example:

class Greeter {
    greeting: string;
    constructor() {
        this.greeting: "Blabla";
    }
    greet= () => {
        alert(this.greeting);
    }
}
like image 71
thomaux Avatar answered Nov 06 '22 16:11

thomaux


The methods on the prototype are the methods that are available on each instance.

class Example {
    constructor(private someProperty: string) {

    }

    method() {
        return this.someProperty;
    }
}

var exampleA = new Example('A');
var exampleB = new Example('B');
var exampleC = new Example('C');

console.log(exampleA.method()); // A
console.log(exampleB.method()); // B
console.log(exampleC.method()); // C

Each instance will have the someProperty and method() copied to its prototype. You can check this using:

alert(exampleC.hasOwnProperty('someProperty') ? 'Yes' : 'No');

It is only when the instance doesn't have its own property that JavaScript will walk up any dependency chain to find the property on a class higher up the dependency chain.

If you supply the code where you are having trouble with the scope of this I'm sure we can help you to fix it.

like image 24
Fenton Avatar answered Nov 06 '22 17:11

Fenton