Home > Blockchain >  JS/TS Accessing method from class returns undefined
JS/TS Accessing method from class returns undefined

Time:10-19

In Typescript / Javascript, given the class:


class T {
    method_a() {
        console.log('Inside method a');
    }
}

I need to access the (unbounded) method like this, but it gots undefined instead:

const method_to_be_passed = T.method_a; // undefined

In python, I would get the unbound method like this:

class P:
    def method_a():
        print('inside method a')

the_method = P.method_a  # <function P.method_a at 0x7fee48eff310>

And then I can bound it to an object to call it. How would I do the equivalent in TS / JS?

The typescript compiler says the following error:

error TS2339: Property 'method_a' does not exist on type 'typeof T'.

CodePudding user response:

In JavaScript, instance methods of a class can be accessed via the class's prototype:

class T {
    method_a() {
        console.log('Inside method a');
    }
}

const method_to_be_passed = T.prototype.method_a;

Note that if you reference the this instance of your class inside your method, you will need to bind your method to some instance of class T like so:

const method_to_be_passed = T.prototype.method_a.bind(some_instance_of_T);

CodePudding user response:

Remember that a class definition in JavaScript/TypeScript is just syntactic sugar (i.e. just shorthand) for defining a constructor-function and prototype properties:

So this

class T {

    val: number = 1;

    method_a() {
        console.log('Inside method a');
    }
}

(I added the val property as an additional example)

Is equivalent to this:

function T() {
    this.val = 1;
}

T.prototype.method_a = function() {
    console.log('Inside method a');
};

Therefore, to get a reference to the method_a function you need to use the prototype qualifier:

const method_to_be_passed = T.prototype.method_a;

This is different to other languages like Python, C#, C , etc that let you reference both instance and non-instance (i.e. static) of a type without additional qualification (of course you cannot meaningfully use instance members without a this parameter, of course).


If you want method_a to not require a this parameter then you need to make it a static member:

class T {

    val: number = 1;

    static method_a() {
        console.log('Inside method a');
    }
}

which does allow you to do this:

const method_to_be_passed = T.method_a;

Playground example:

https://www.typescriptlang.org/play?target=1#code/MYGwhgzhAEASkEkB2EAuYnAKYFksFsAjLAJxgG8AoS6W6ANzBAC5okBXI06AXmgEYA3NTrQA5llQMmABRDsI-ABQBKVhy4loVUaJKT2JJNFQALAJYQAdIxDQA1AOGiAviLrmU6TFgBi7TFVtGl1aYAB7FHCQLCsQcLElAHJPNAxsf0wklWc6NzdKUEgYeAgAZXRUc2A8TQgqENo0quBpFjZOYi0 IXcmyurxSTa5BWU1Ds1g0Np9VENjUoqwFtqu61sHJ0boAtFmwYPgTOAgnRmIqJi4hOSjk zc2nygA

  • Related