简体   繁体   中英

Declaring TypeScript member in prototype rather than adding to 'this'

The following TypeScript:

class A {
    member = "value";
}

...is compiled to:

var A = (function () {
    function A() {
        this.member = "value";
    }
    return A;
})();

I want to achieve the following:

var A = (function () {
    function A() {
    }

    A.prototype.member = "value";

    return A;
})();

The reason for this is that I believe that the latter construct could be more efficient because (1) the assignment this.member = "value" statement would not have to be executed every time a new instance is created, and (2) instance memory payload would be smaller.

Disclaimer: I haven't bench marked the two constructs so I really don't know whether that is the case.

So my question is: Is it possible to declare a "prototype member" using type script? .

I'd also be happy if someone could explain why type script is designed this way? . (See §8.4.1 in the specification )

I understand that it would be stupid to declare mutable members in this way, but declarations of immutable primitives, like string and number , should be fine to set on the prototype, right?

A possible work around could be:

class A {
    member: string;
}

A.prototype.member = "value";

However, that won't work for private members:

class A {
    private member: string;
}

A.prototype.member = "value"; // error TS2107: 'A.member' is inaccessible.

Is it possible to declare a "prototype member" using type script?

No the language doesn't allow this at the moment.

Workaround

When the compiler is unhappy ... assert:

class A {
    private member: string;
}

(<any>A.prototype).member = "value"; // suppressed

why type script is designed this way

Simply because it is non-idiomatic to have non functions on prototype .

(1) the assignment this.member = "value" statement would not have to be executed every time a new instance is created, and (2) instance memory payload would be smaller.

However lookup will definitely be slower. Here is a sample test : http://jsperf.com/prototype-vs-this-access

I came up with a possible work around that works for private members too:

class A {
    private member: string;

    static __init = (() => {
        A.prototype.member = "value";
    })();
}

This is pretty nice; all code is within the class construct and I've avoided casting to any so it is still possible to track references to those private members (for refactoring, etc.).

A dummy __init member is declared on the class function when using this approach. Not a big issue though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM