从Typescript中的实例访问静态方法

Gle*_*shi 7 javascript static typescript

为什么我不能这样做?是由于Javascript/Typescript的技术限制,还是由Typescript的开发人员做出的设计决定?这个相同的代码在Java或C#中可以正常工作.

class Test {
  static str: string = "test";
  public static getTest(): string {
    return this.str;
  }
}

//works as expected
console.log(Test.getTest());
//won't compile
var test: Test = new Test();
console.log(test.getTest());
Run Code Online (Sandbox Code Playgroud)

bas*_*rat 6

但我还是想知道为什么。

少魔法。静态属性存在于Classnot 实例上。它很清楚从代码中调用了什么,而不是在运行时魔术绑定到类或成员函数。

是由于 Javascript/Typescript 的技术限制,还是 Typescript 开发人员的设计决定

不是技术限制。一个设计决策。与 ES6 保持一致比什么都重要:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static但在那里,它做出了一个不那么神奇的决定


Dan*_*ger 6

正如@basarat 所说,这只是一个设计决策,而不是技术限制。

实际上,尽管无法test.getTest()像在 Java 或 C# 中那样访问它,但还是有一些方法可以访问它:

Object.getPrototypeOf ()(替换现在已弃用的Object.prototype.__proto__)或Object.prototype.constructor应该可以工作:

Object.getPrototypeOf(test).constructor.getTest();

test.constructor.getTest();
Run Code Online (Sandbox Code Playgroud)

实际上:

Object.getPrototypeOf(test).constructor === test.constructor; // true
Run Code Online (Sandbox Code Playgroud)

在这里您可以看到正在运行的编译源:

Object.getPrototypeOf(test).constructor.getTest();

test.constructor.getTest();
Run Code Online (Sandbox Code Playgroud)

请注意,静态属性存在于类中,但不存在于实例中。

因此,如果你想从test它的原型开始,你应该调用Object.getPrototypeOf(test),而不是test.prototype,这是完全不同的事情。

.prototype属性仅存在于函数中,并且当使用构造函数 ( ) 实例化新对象new并调用该构造函数 ( new Test()) 时,该属性将成为新创建的对象的原型(已弃用的.__proto__)。

在你的例子中:

test.prototype;                     // undefined
Test;                               // class Test { static getTest() { ... } }
Test.protoype;                      // { constructor: class Test { ... } }
Test.protoype.constructor;          // class Test { static getTest() { ... } }
Test.protoype.constructor === Test; // true
test.constructor;                   // class Test { static getTest() { ... } }
test.constructor === Test;          // true

Object.getPrototypeOf(test) === Test.prototype; // true
Run Code Online (Sandbox Code Playgroud)