static-methodsmixinsqooxdoo

Access static members in mixins


The instruction this.constructor doesn't work in mixins. I get an undefined value. I wonder why it happens and is it possible to use this instruction. There is a code example:

qx.Mixin.define("MZoomable", {
    statics: {
      MAX_ZOOM: 500
    },
    
    members: {
      printMaxZoom: function(){
        alert(this.constructor.MAX_ZOOM);
      }  
    }
    
});

qx.Class.define("MyClass", {
  extend: qx.core.Object,
  include: [MZoomable],
  
  constuct: function(){
    this.base(arguments);
  }
});

const o = new MyClass();
o.printMaxZoom();

alert in printMaxZoom will show undefined word.


Solution

  • The answer is that this.constructor refers to the class of the object at runtime, and that would be MyClass. I would expect that if you modified printMaxZoom to be:

    printMaxZoom: function(){
      alert(this.constructor === MyClass);
    }
    

    Then you would get an alert that says "true".

    This is an inherent characteristic an environment where the type is determined (including the addition of a mixin) at runtime.

    If you want to refer to static members of a Mixin, you should use the absolute syntax, eg:

    printMaxZoom: function(){
      alert(MZoomable.MAX_ZOOM);
    }
    

    Note that it is always good practice to use the absolute path for static variables, and it is often a bug to use this.constructor as a shortcut.

    For example:

    qx.Class.define("MyClassOne", {
      extend: qx.core.Object,
      
      construct: function(){
        this.base(arguments);
        alert(this.constructor.MY_VALUE);
      },
    
      statics: {
        MY_VALUE: 23
      }
    });
    
    
    qx.Class.define("MyClassTwo", {
      extend: MyClassOne
    });
    
    // creates an alert that says "23"
    var one = new MyClassOne();
    
    // creates an alert that says "undefined"
    var one = new MyClassTwo();
    

    The issue is the same as the one in your question, in that this.constructor is the actual class of the object, and not the class (or mixin) where the this.constructor statement appears.