skip to Main Content

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 ‘extendObject.
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


  1. 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.

    class Test extends Object{
    
    }
    
    console.log(Test.values({key:'value'}));
    
    // no base class
    class Test2{
        test = 'test'
    }
    
    // check that Object.prototype is used
    console.log(new Test2 instanceof Object);
    console.log(new Test2().hasOwnProperty('test'));
    
    // but sorry, no static methods   
    console.log(Test2.values({key:'value'}));
    Login or Signup to reply.
  2. 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 extending another class, the prototype of the constructor function is Function.prototype, not Object.prototype.

    class A {}
    class B extends Object {}
    
    console.log(Object.getPrototypeOf(A) === Function.prototype); // true
    console.log(Object.getPrototypeOf(A) === Object); // false
    console.log(Object.getPrototypeOf(B) === Object); // true

    Function.prototype doesn’t have properties like keys or entries, but it does have properties like apply, call, and bind, 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 from Object.entries, then Function.entries would do the same, which I think would be counter-intuitive.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search