Search code examples
javascriptecmascript-6clonees6-class

Cloning extended objects in Javascript, keeping all father's methods


I cannot achieve a complete and satisfactory cloning method in JS. I have this father class, with properties and methods, of course each derived class must access to such father's methods

class Father {
    constructor() {
        this.fatherProp = 1;
    }

    fatherMethod() {
        console.log('father method');
    }
}

and this child class, that extends the previous one

class Child extends Father {
    constructor() {
        super();
        this.childProp = 2;
    }
}

The client code works fine

let child1 = new Child();
console.log(child1); // CONSOLE: Child {fatherProp: 1, childProp: 2}
child1.fatherMethod(); // CONSOLE: father method

Then, I need to clone the child object, of course keeping all the same father/child classes structure, properties and method. So I added a clone method in Father class

class Father {
    constructor() {
        this.fatherProp = 1;
    }

    fatherMethod() {
        console.log('father method');
    }

    clone() {
        let newObject = {};
        Object.assign(newObject, this);
        return newObject;
    }
}

Client code works so-and-so.

let child2 = child1.clone();
console.log(child2); // CONSOLE: {fatherProp: 1, childProp: 2} *** "Child" type missing
child2.fatherMethod(); // CONSOLE: Uncaught TypeError: child2.fatherMethod is not a function

Deeply logging the two objects I can see that first child (blue in the picture) has "father" as "__proto". While second object (red) has empty __proto

enter image description here

What's going on? How should I clone an object in this case? Thank you


Solution

  • Your clone method return an object instead of a Class, one way:

    class Father {
        constructor() {
            this.fatherProp = 1;
        }
    
        fatherMethod() {
            console.log('father method');
        }
    
        clone() {
            let clone = Object.assign( Object.create( Object.getPrototypeOf(this)), this);
            return clone;
        }
    }
    
    class Child extends Father {
        constructor() {
            super();
            this.childProp = 2;
        }
    }
    
    
    let child1 = new Child();
    console.log(child1); // CONSOLE: Child {fatherProp: 1, childProp: 2}
    child1.fatherMethod(); // CONSOLE: father method
    
    let child2 = child1.clone();
    console.log(child2); // CONSOLE: {fatherProp: 1, childProp: 2} *** "Child" type missing
    child2.fatherMethod(); // CONSOLE: Uncaught TypeError: child2.fatherMethod is not a function