【问题标题】:Accessing static methods from instance in Typescript从 Typescript 中的实例访问静态方法
【发布时间】:2016-02-25 03:41:00
【问题描述】:

为什么我不能这样做?是由于 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());

【问题讨论】:

    标签: javascript static typescript


    【解决方案1】:

    正如@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
    

    【讨论】:

      【解决方案2】:

      但我还是想知道为什么。

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

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

      不是技术限制。一个设计决定。与 ES6 保持一致比其他任何事情都重要:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static 但在那里,它的决定是为了减少魔法

      【讨论】:

      • 更新了我的问题,提出了一个更清晰的问题:是由于 Javascript/Typescript 的技术限制,还是这是 Typescript 开发人员的设计决定?听起来您是在告诉我后者是为了让开发人员更清楚。
      猜你喜欢
      • 2023-03-07
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 2015-08-05
      • 1970-01-01
      • 2014-02-19
      • 2013-04-18
      相关资源
      最近更新 更多