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

15

为什么我做不到这一点?这是由于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());
2个回答

8
但我仍然想知道为什么。
更少的魔法。静态属性存在于“类”而不是实例上。从代码中清楚地看到正在调用什么,而不是在运行时绑定到类或成员函数的魔术。
这不是技术限制。这是一个设计决策。更多地与ES6对齐而不是其他任何事情:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static但那里做出这个决定是为了减少魔术。

我更新了我的问题以更清晰地表达:这是由于Javascript/Typescript的技术限制,还是Typescript开发人员的设计决策?听起来你告诉我这是后者,为了让开发人员更清楚。 - Glen Takahashi

6

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

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

使用Object.getPrototypeOf()(替代已弃用的Object.prototype.__proto__) 或 Object.prototype.constructor 都可行:

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

test.constructor.getTest();

实际上:

Object.getPrototypeOf(test).constructor === test.constructor; // true

在这里,您可以看到编译源代码的效果:

class Test {
  static getTest() {
    return this.str;
  }
}

Test.str = 'test';

const test = new Test();

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

console.log(Object.getPrototypeOf(test).constructor === test.constructor);
console.log(Object.getPrototypeOf(test) === Test.prototype);

注意静态属性存在于类中而不存在于实例中。

因此,如果您想从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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接