In JavaScript If I create a class with a static method and then create a subclass of that class, I can call the static method using subclass name too (static methods are inherited).
Object class which is superclass of all classes has many static methods.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
But why none of those methods can be called using any of subclass names ?
update:
I noticed some suggested to explicitly ‘extend‘ Object.
But Object class is already superclass of every class in JavaScript. the proof is the .toString() method that every object from every class has it and we know it is inherited from Object class even if you don’t explicitly write ‘extends Object’.
So every class is implicitly extending Object (directly or through inheritance chain) but why non-static methods are being inherited automatically and not the static methods?
as for sample code:
class Test {
constructor() {}
}
const test = new Test();
console.log(test.toString()); // works, inherited from Object class
console.log(Test.<any static method of Object>)); // doesn't work
2
Answers
The OP asked why Test should be extended with Object in order static methods to work.
Well, JS classes is a ES6 feature. Before that only prototypes exist.
JS classes require explicit extending from a base class.
When you omit this, the class’ instances
are extended from Object with Object.prototype
so no static methods.
Remember that originally JavaScript didn’t have classes. When the concept was introduced, it was basically implemented as syntax sugar over constructor functions, which are instances of
Function
.When resolving static properties and methods, what matters is the prototype of the constructor function itself (not the prototype of instances created from that constructor). For a class defined without
extend
ing another class, the prototype of the constructor function isFunction.prototype
, notObject.prototype
.Function.prototype
doesn’t have properties likekeys
orentries
, but it does have properties likeapply
,call
, andbind
, which is why you can call these functions on any function. So in your example,Test.apply
does have a value.If
Test.entries
were to inherit fromObject.entries
, thenFunction.entries
would do the same, which I think would be counter-intuitive.