在原型中声明TypeScript成员而不是添加到'this'

时间:2015-01-08 21:32:38

标签: javascript typescript

以下TypeScript:

class A {
    member = "value";
}

...编译为:

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

我想实现以下目标:

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

    A.prototype.member = "value";

    return A;
})();

这样做的原因是我相信后一种结构可能更有效率,因为(1)每次创建新实例时都不必执行赋值this.member = "value"语句,并且(2)实例内存负载会更小。

免责声明:我没有替换标记这两个结构,所以我真的不知道是否是这种情况。

所以我的问题是:是否可以使用类型脚本声明“原型成员”?

如果有人可以解释为什么类型脚本是这样设计的,我也很高兴?。 (见§8.4.1 in the specification

我理解用这种方式声明可变成员是愚蠢的,但是stringnumber之类的不可变原语的声明应该可以在原型上设置,对吧?

可能的解决办法是:

class A {
    member: string;
}

A.prototype.member = "value";

但是,这对私人会员不起作用:

class A {
    private member: string;
}

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

2 个答案:

答案 0 :(得分:5)

  

是否可以使用类型脚本声明“原型成员”?

目前没有语言不允许这样做。

解决方法

当编译器不满意时...断言:

class A {
    private member: string;
}

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

为什么类型脚本是这样设计的

仅仅因为在prototype上拥有非功能是非惯用的。

  

(1)每次创建新实例时都不必执行赋值this.member =“value”语句,(2)实例内存有效负载会更小。

然而,查找肯定会慢一些。以下是一个示例测试:http://jsperf.com/prototype-vs-this-access

答案 1 :(得分:3)

我想出了一个适用于私人会员的可能的工作:

class A {
    private member: string;

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

这很不错;所有代码都在类构造中,并且我避免转换为any,因此仍然可以跟踪对这些私有成员的引用(用于重构等)。

使用此方法时,在类函数上声明了一个虚拟__init成员。虽然不是一个大问题。