1

I would like to have a base class and an inheriting class. The base class should provide some general functionality which depends on the properties of the inheriting class.

=>How can I access the properties of the inheriting class in the base class?

Below is some example to illustrate the question (My question is not how to define an enum in JavaScript. The example is just for illustration.).

Example base class:

export default class Enum { 

    constructor(name){
        this.name = name;       
    }
}

Enum.values =  function(){
    return Object.values(INHERITING_CLASS);
};


Enum.forName = function(name){
    for(var enumValue of INHERITING_CLASS.values){
        if(enumValue.name === name){
            return enumValue;
        }
    }
    throw new Error('Unknown value "' + name + '"');
} 

Example inheriting class:

import Enum from './enum.js';

export default class ColumnType extends Enum {  

    constructor(name, clazz){
        super(name);        
        this.associatedClass = clazz;
    }
}

ColumnType.Integer = new ColumnType('Integer', Number);
ColumnType.Double = new ColumnType('Double', Number);
ColumnType.String = new ColumnType('String', String);

I want to be able to access the static values of ColumnType with

ColumnType.values()

where the values function is provided by the base class Enum. Some for method forName.

If I would use "Enum" for the placeholder INHERITING_CLASS, the result is not correct.

=> How do I know that ColumnType is the currently inheriting class while being in the scope of the definition of the Enum class?

Edit

Here is a related question:

Get parent class name from child with ES6?

Their answer uses instance.constructor. However, in my static method I don't have an instance.

Stefan
  • 10,010
  • 7
  • 61
  • 117
  • 1
    Javascript differs from classical inheritance, you may want to read up on Prototype in Javascript – Harry Mar 13 '19 at 12:20
  • Can you show how you would write this in Java? Surely you would declare a protected attribute with the values that the child class would need to overwrite? – Bergi Mar 13 '19 at 12:52
  • Thank you for asking back. I *thought* I already did that in Java but it turns out it has been something different (non static). – Stefan Mar 14 '19 at 08:30

2 Answers2

0

It is easier than I thought. When calling the static method ColumnType.values(), inside the values function this will actually provide the wanted Class as context:

export default class Enum { 

    constructor(name){
        this.name = name;       
    }
}

Enum.values =  function(){
    return Object.values(this);
};


Enum.forName = function(name){
    for(var enumValue of this.values){
        if(enumValue.name === name){
            return enumValue;
        }
    }
    throw new Error('Unknown value "' + name + '"');
} 
Stefan
  • 10,010
  • 7
  • 61
  • 117
  • I thought you were looking for a way to access properties of a child class from an parent's class object or parent's class. Seems like you were looking for some form of polymorphism, is that the case ? – Akheloes Mar 13 '19 at 12:49
  • The word polymorphism did not pop to my mind but you are right. – Stefan Mar 13 '19 at 12:58
  • In that case you might want to rephrase the title of the thread, it's confusing imo :) – Akheloes Mar 13 '19 at 19:26
-1

I think what you're looking for is the prototype unless I misread the question

ColumnType.prototype.values()

Matt Pengelly
  • 1,480
  • 2
  • 20
  • 34
  • How do I know that ColumnType is the currently inheriting class while being in the scope of the definition of the Enum class? – Stefan Mar 13 '19 at 12:22
  • One thing I think you could do is call ColumnType.prototype.values.bind(this) and then within the parent implementation reference this though that might night be the cleanest solution. There's also a property on the function object called caller. So Function.caller would work. But it's also a somewhat dirty solution. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller – Matt Pengelly Mar 13 '19 at 12:32