简体   繁体   中英

Accessing static methods from instance in Typescript

Why can't I do this? Is it due to technical limitations of Javascript/Typescript, or is this a design decision by the developers of Typescript? This same code would work fine in Java or 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());

but I'd still like to know why.

Less magic. Static properties exist on the Class not instances. Its clear exactly what is getting called from the code instead of magic binding to class or member function at runtime.

Is it due to technical limitations of Javascript/Typescript, or is this a design decision by the developers of Typescript

Not a technical limitation. A design decision. More to align with ES6 than anything else : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static But over there its a decision made for less magic

As @basarat says, it's just a design decision, not a technical limitation.

Actually, even though it's not possible to access test.getTest() just like you would in Java or C#, there are ways to access it:

Both Object.getPrototypeOf() (replacement to the now deprecated Object.prototype.__proto__ ) or Object.prototype.constructor should work:

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

test.constructor.getTest();

Actually:

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

Here you can see the compiled source in action:

 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);

Note static properties exist in classes but not in instances.

Therefore, if you want to go from test to its prototype, you should call Object.getPrototypeOf(test) , not test.prototype , which is a completely different thing.

The .prototype property only exists in functions and, when instantiating a new object using new and a call to that constructor function ( new Test() ), will become the newly created object's prototype (the deprecated .__proto__ ).

In your example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM