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());
A static method cannot access a class's instance variables and instance methods, because a static method can be called even when no objects of the class have been instantiated. For the same reason, the this reference cannot be used in a static method.
The static members of a class are accessed using the class name and dot notation, without creating an object e.g. <ClassName>. <StaticMember>. The static members can be defined by using the keyword static. Consider the following example of a class with static property.
A static method uses the static keyword instead of the function keyword when we define it. Static members can be encapsulated with the public, private and protected modifiers. We call a static method directly on the class, using the class name and dot notation. We don't need to create an object instance.
TypeScript was developed by Microsoft to make it easier to write large code bases. Essentially, it's just JavaScript, with static typing.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With