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

时间:2015-11-23 05:18:27

标签: 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());

2 个答案:

答案 0 :(得分:3)

  

但我仍然想知道原因。

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

  

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

不是技术限制。一个设计决定。更多地与ES6保持一致:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static但是在那里它决定了更少的魔法

答案 1 :(得分:0)

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