Trying out ES6 and tried to create a class with static properties and function for parsing. Then I want to extend the base parser for each different type I am parsing. Not sure if I am doing a anti-pattern but I cannot override static properties.
This is my base parser
class Module {
static name = 'Default Module'
static version = {major:10000, minor: 10000}
static checkVersion({majorVersion = 10000, minorVersion = 10000}) {
if(this.version.major !== majorVersion || this.version.minor > minorVersion) {
throw `${this.name} requires version ${this.version.major}.${this.version.minor} got ${majorVersion}.${minorVersion}`;
}
}
static parse(data) {
try {
this.checkVersion(data);
return this.internalParser(data);
} catch (e) {
throw e;
}
}
static internalParser(data) {
throw `${this.name} has no parser implemented`;
}
}
And then I want to extend like this
class ExtendedModule extends Module {
static name = 'Extended';
static version = {major: 1, minor:0}
static internalParser(data) {
//Some stuff
}
}
But when compiling in node with babel I get
true; if ('value' in descriptor) descriptor.writable = true; Object.defineProp
^
TypeError: Cannot redefine property: name
at Function.defineProperty (native)
Anyone got a clue if this is even possible or just plain wrong?
Classes are functions (in transpiled code), and when you define static properties, they are attached directly to the class constructor function, so:
class Foo {
static name = 'foo';
}
is the same as doing
function Foo(){}
Object.defineProperty(Foo, 'name', {
configurable: true,
writable: true,
value: 'foo'
});
If you try doing that in your browser, you will get an error, which is exactly what you are seeing. This is because the function already has a property called name
and it is Foo
. In ES5, the name property was configurable: false
, so what you are trying to do will not work, hence the TypeError: Cannot redefine property: name
error and you need to rename your static to something else.
In ES6, name
is actually configurable: true
so what you are trying to do will work eventually, but browsers need to update themselves first.
The bigger question here is why you need to use a class. If you are using all static variables, you might as well just use a module that exports everything directly without the class, and wrap it. It have a module that exports a creation function that you pass an innerParser
method or something. Your current code way over-uses classes.