Search code examples
javascripttypescriptprototypemixins

Assign all methods and properties of prototype B into prototype A?


I have a class A that is a subset of class B. It shares many of the properties and methods of class B.

Class A lacks implementation though. So I want all all functionality in class B to to go into class A.

ClassA.prototype = ClassB.prototype;

or

ClassA.prototype += ClassB.prototype

But it seems I have to:

ClassA.prototype.methodA = ClassB.prototype.methodA
ClassA.prototype.methodB = ClassB.prototype.methodB
ClassA.prototype.methodC = ClassB.prototype.methodC
ClassA.prototype.methodD = ClassB.prototype.methodD

for every single method and property. Is there no way I can put implementations in B into A at once?


Solution

  • It's true you can't overwrite the prototype property of functions created via class syntax, because it's both read-only and non-configurable. You can do it if you use function syntax instead as Fullstack Guy points out.

    But you probably want to make ClassA extend ClassB:

    class ClassA extends ClassB {
        // ...
    }
    

    Live Example:

    class ClassB {
        methodA() {
            console.log("methodA");
        }
        methodB() {
            console.log("methodB");
        }
        methodC() {
            console.log("methodC");
        }
        methodD() {
            console.log("methodD");
        }
    }
    class ClassA extends ClassB {
        // ...
    }
    new ClassA().methodA();

    If not, though, you can copy all the methods using a loop:

    for (const name of Object.getOwnPropertyNames(ClassB.prototype)) {
        const method = ClassB.prototype[name];
        if (typeof method === "function") {
            ClassA.prototype[name] = ClassB.prototype[name];
        }
    }
    

    Live Example:

    class ClassB {
        methodA() {
            console.log("methodA");
        }
        methodB() {
            console.log("methodB");
        }
        methodC() {
            console.log("methodC");
        }
        methodD() {
            console.log("methodD");
        }
    }
    class ClassA {
        // ...
    }
    for (const name of Object.getOwnPropertyNames(ClassB.prototype)) {
        const method = ClassB.prototype[name];
        if (typeof method === "function") {
            ClassA.prototype[name] = ClassB.prototype[name];
        }
    }
    new ClassA().methodA();

    But note that if ClassB is a subclass, super within the methods will continue to access ClassB's superclass methods, it won't either be invalid or access ClassA's superclass methods.