1

I have a javascript scenario where I have created a base class and a derived class and wish to pack the total set of properties into a JSON-string with JSON.stringify().

When I use the equivalent to the code below I only get the child-object's properties when I run "toString()" on one of the DerivedClass instances:

function BaseClass() {
    this.version = "0.0.0";
    this.time = Date.now();
    this.type = this.constructor.name;
}

BaseClass.prototype.BaseClassException = function(message) {
    this.message = message;
}

BaseClass.prototype.toString = function() {
    return JSON.stringify(this);
}

BaseClass.parse = function(jsonString) {
    var json = JSON.parse(jsonString);

    switch(json.type) {
    case "DerivedClass1":
        return new DerivedClass1();
    case "DerivedClass2":
        return new DerivedClass2();
    default:
        throw new BaseClassException("No compatible type found when parsing: " + jsonString);
}

function DerivedClass1(prop1, prop2) {
    this.prop1 = prop1;
    this.prop2 = prop2;
    this.type = this.constructor.name;
}
DerivedClass1.prototype = new BaseClass();
DerivedClass1.prototype.constructor = DerivedClass1;

function DerivedClass2(prop3) {
    this.prop3 = prop3;
}
DerivedClass2.prototype = new BaseClass();
DerivedClass2.prototype.constructor = DerivedClass2;


// Test
var dc1 = new DerivedClass1("A", "B");
console.log(dc1.toString());  // Returns JSON-string with properties of DerivedClass1, but not BaseClass

There will be several different derived classes. While I do know that js doesn't really support classes I would still like to pack all the properties from the base and child objects in the same JSON-string. The structure is necessary to correlate to the other nodes of the total system, ie all properties need to be present.

If anyone at the same time has the knowledge of nudging me in the correct direction to understand the link between the child object and parent object in order for me to better understand the "inheritance" part of js I'd be really thankful as well. I more used to strict oo-languages so I'd be happy to learn.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
dargolith
  • 321
  • 4
  • 14
  • 2
    JavaScript features prototypical inheritance which is about sharing _functionality_ and not structure. See [this question and answers](http://stackoverflow.com/q/17008086/1348195), in my answer there I argue your case though. – Benjamin Gruenbaum May 22 '14 at 12:40
  • @BenjaminGruenbaum Thank you, I will read it! – dargolith May 22 '14 at 14:10

1 Answers1

2

There are two things which I can readily suggest.

  1. To invoke the base class constructor, you have to invoke it manually like this

    function DerivedClass1(prop1, prop2) {
        BaseClass.call(this);
        this.prop1 = prop1;
        this.prop2 = prop2;
        this.type = this.constructor.name;
    }
    

    We invoke the parent constructor function, with the current object. The important thing to note here is that, we are setting the current context to the object of type DerivedClass1.

  2. To actually do prototypal inheritance, you need to use the base class's prototype, not the object.

    DerivedClass1.prototype = Object.create(BaseClass.prototype);
    

    In your case, BaseClass's constructor doesn't depend on any arguments. So, doing DerivedClass1.prototype = new BaseClass(); will not make a big difference. But it is always better to depend only on the Parent constructor's prototype. Read more about using Object.create for inheritance, in this wonderful answer.

Community
  • 1
  • 1
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • 2
    Note, a way for you to think about this coming from Java is that in JavaScript, the `super` call is explicit. While in Java calling `super` is optional in derived classes, in JavaScript you have to call `BaseClass.call(this)` if you want explicit construction with the base class constructor. While this is inaccurate it should give you good intuition. – Benjamin Gruenbaum May 22 '14 at 12:38
  • Also doing `DerivedClass1.prototype = new BaseClass();` is perfectly fine for inheritance in OP's case, but I agree Object.create is better here. – Benjamin Gruenbaum May 22 '14 at 12:39
  • @BenjaminGruenbaum + thefourtheye The fast and high quality answers you guys and this community can provide are really amazing. Thank you for sharing your knowledge! I hope it proves useful to many others as well. :) – dargolith May 22 '14 at 14:07