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