4

I have created a class as per the official examples from MDN(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)

Here is my code

class A {
}

const Mixer = BaseClass => class extends BaseClass {
    static val = 10;
}

class B extends Mixer(A) {
    myMethod() {
    // Need some way to access the static member "val"
    }
}

How do I access "val"?

Without mixin(ie class B extends A, and val being a static in class A) I could have done "A.val".

In this scenario, Mixer.val does not work and as per my understanding B extends from an anonymous class, so there is no way to access the super class by name.

Edit: I put the question wrongly. My real problem was to access val in the Mixer itself. Accessing val in B is straight forward, as pointed out my the answers.

For example

const Mixer = BaseClass => class extends BaseClass {
    static val = 10;
    myMethod2() {
        // log the val member
    }
}
Tarun Gehlaut
  • 1,292
  • 10
  • 16

3 Answers3

3

This was already discussed on SO numerous times, but this case likely needs some explanation. Generally, static properties and methods can be accessed from instance methods with this.constructor:

class B extends Mixer(A) {
    myMethod() {
      console.log(this.constructor.val);
    }
}

Where this.constructor === B, but this won't be true in classes that inherit from B.

There is no reason to refer to parent anonymous class directly in B, because val is inherited from it through prototype chain. This is the purpose of class inheritance.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • Thanks for the update. I have changed my question. – Tarun Gehlaut Sep 30 '17 at 15:39
  • It will still be `this.constructor.val`. You can make it named class like `=> class MixinClass extends BaseClass` and refer it as `MixinClass.val`, but you don't even need to. `this.constructor` handles this. – Estus Flask Sep 30 '17 at 15:52
  • Thanks, this.constructor solved the problem. I wanted to experiment with anonymous classes, so didnt make a named one. – Tarun Gehlaut Sep 30 '17 at 15:54
0

That is because class fields are not yet in the ECMAScript standard. Your code works perfectly fine if you compile it with BabelJS and paste it to the browser console afterwards.

class B extends Mixer(A) {
    myMethod() {
        console.log(B.val); // logs 10
    }
}

If you need to use ES2015 a quick trick is to use setters and getters.

class A {
}

var val = 10;
const Mixer = BaseClass => class extends BaseClass {
    static get val() {
      return val;
    }

    static set val(newVal) {
      val = newVal;
    }
}

class B extends Mixer(A) {
    myMethod() {
    // Need some way to access the static member "val"
    }
}

// Use it
B.val; // 10
B.val = 15;
B.val; // 15
NicolaeS
  • 423
  • 2
  • 7
  • True it will be available in class B, as B.val, but what if I need to access the val in the Mixer class itself? I am not sure of the getters and setters approach, as it is polluting the global namespace. – Tarun Gehlaut Sep 30 '17 at 13:51
0

The es6 do not support static attribute, I dont know what babel do with the static val,but the truth is that what you test dont base on es6 specification. So you may use the static function to do the test

sinbar
  • 933
  • 2
  • 7
  • 25