How do you define a static constructor within a JS class?
I managed to write something that somehow works but it requires to write a specific codepath in constructor
for when an IngredientsDB
object is instantiated from the static method IngredientsDB.fromXML()
:
class IngredientsDB {
constructor(...args) {
if (arguments.length === 0) {
this.document = null;
} else {
this.document = new DOMParser().parseFromString("<ingredients/>", "text/xml");
// ... process args
}
}
static fromXML(xmlString) {
const db = new this;
db.document = new DOMParser().parseFromString(xmlString, "text/xml");
return db;
}
toString() { // concise output for testing
const ingredientsNode = this.document.firstChild;
let str = ingredientsNode.tagName + ":";
let childNode;
for (childNode of ingredientsNode.children)
str += " " + childNode.tagName;
return str;
}
}
const xml = document.getElementById("ingredients").textContent.trimStart();
console.log(IngredientsDB.fromXML(xml).toString());
<script id="ingredients" type="text/xml">
<ingredients>
<tomato/>
<meat/>
<cheese/>
</ingredients>
</script>
2
Answers
Here's an attempt at addressing the problem of detecting when the constructor is called from a class method. The idea is to use a private static property that defines the "operating mode" of the constructor:
You can define a normal
static
method, do the XML parsing and pass the parsed arguments to the normal constructor, then return the constructed object.Note
this
refers to the "receiver" of a method call. Which in the case ofIngredientsDB.fromXML(xml)
isIngredientsDB
. You could also useIngredientsDB
instead ofthis
.If a constructor does not allow for a specific scenario you could define instance methods that allow you to construct a specific instance and then alter the state.