Julian
Julian

Reputation: 2835

How can I call my class' parent's parent's constructor in ES6?

I'm using ES6 classes and my class (A) extends class B and class B extends class C. How can A extend a method and then call C's version of that method.

class C {
  constructor() {
    console.log('class c');
  }
}

class B extends C {
  constructor() {
    super()
    console.log('no, I don\'t want this constructor.');
  }
}

class A extends B {
  constructor() {
    // What should I be doing here?  I want to call C's constructor.
    super.super();
  }
}

Edit: Thanks all, I'm going to stop trying to do this silly thing. The minor gains in code-re-use aren't worth the acrobatics in my situation.

Upvotes: 5

Views: 1305

Answers (5)

Gio
Gio

Reputation: 3340

You need quite some acrobatics, and I don't think I would recommend this form a 'clean / transparent code' point of view, however it can be done as follows:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<script type="text/javascript">

class C {
  constructor() {
      this.fooExtension = null;
  }

  initC(aFoo) {
    this.fooExtension = aFoo;
  }

  foo() {
    if (this.fooExtension === null) {
        console.log('fooFromC');
    } else {
        console.log('extend foo called from C');
        this.fooExtension();
    }
  }
}

class B extends C {
  constructor() {
    super();
  }

  foo() {
    super.foo();
  }
}

class A extends B {
  constructor() {
    super();

    let fooExtension = function() {
      console.log('fooFromA');
    };

    this.initC(fooExtension);
  }
}

c = new C();
c.foo();

a = new A();
a.foo();

</script>
</head>
<body>
</body>
</html>

This will result in the following output:

fooFromC
extend foo called from C
fooFromA

Upvotes: 0

mtizziani
mtizziani

Reputation: 1016

class C {
  constructor(){
    console.log('C');
  }
}

class AB extends C {
  constructor(){
    super();
  }
}

class B extexts AB {
  constructor(){
    super();
    console.log('B');
  }
}

class A extends AB {
  constructor(){
    super();
  }
}

i think building a class between both and extend A and B from it is the only way because evere constructor has to call his own super constructor first.

new B(); // output is CB
new A(); // output is C

Upvotes: 0

Ry-
Ry-

Reputation: 225164

You can’t not call the parent’s constructor in an ES6 class. Judging by your comment, maybe you should try something like this?

class Mixin {
  static include(constructor) {
    const descriptors = Object.getOwnPropertyDescriptors(Mixin.prototype);

    Object.keys(descriptors).forEach(name => {
      Object.defineProperty(constructor.prototype, name, descriptors[name]);
    });
  }

  someCommonFunction() {
    // Perform operation common to B and C
  }
}

delete Mixin.prototype.constructor;

class B extends A {
}

Mixin.include(B);

class C extends A {
}

Mixin.include(C);

Upvotes: 5

dfsq
dfsq

Reputation: 193311

Simple but ugly way is to check for instance A in B's constructor:

class B extends C {
  constructor() {
    super()
    if (!(this instanceof A)) {
      console.log('no, no no, I don\'t want this!');  
    }
  }
}

class A {
  constructor() {
    console.log('class c');
  }
}

class B extends A {
  constructor() {
    super()
    if (!(this instanceof C)) {
      console.log('no, no no, I don\'t want this!');  
    }
  }
}

class C extends B {
  constructor() {
    super();
  }
}

const c = new C()

Upvotes: 1

Labib Ismaiel
Labib Ismaiel

Reputation: 1340

the best way i can think of, which might not necessarily be the best way, is the to define a function in B that calls A's super(), that way you will inherit that in C by extension and you will have it there ready to go.

Upvotes: 0

Related Questions