class properties inheritance

# Антон Шувалов (10 years ago)

guys! I'm confused with class properties. With prototype chains I can setup kinda default values which being replaced by values from children. But replacing become hard to work with classes. For example, we have simple module, some backbone view:

class BaseView extends Backbone.View {
  constructor() {
    this.tagName = 'div';
    super(); // create element from this.tagName value
  }
}

And now we create inherited view:

class Span extends BaseView {
  constructor() {
    this.tagName = 'span'
    super();
  }
}

But all this variables will be replaced by parent, not by child. It's kinda weird. Another example with prototype chains works fine:

var BaseView = Backbone.View.extends({
  tagName: 'div'
})
var Span = Backbone.View.extends({
  tagName: 'span'
});

How I can do similar things with es6 classes? Sorry if this question is already discussed.

# Frankie Bagnardi (10 years ago)

That's why you call super(); as the first line in the constructor.

# Claude Pache (10 years ago)

Le 28 déc. 2014 à 23:14, Frankie Bagnardi <f.bagnardi at gmail.com> a écrit :

That's why you call super(); as the first line in the constructor.

The true rule is not: "call super() in the first line in the constructor"; it is: "don't reference this before calling the super constructor".

# Claude Pache (10 years ago)

There is more than one way to resolve your problem. Here are those I see:

(1) Use a getter:

class BaseView extends Backbone.View {
    get tagName() { 
        return 'div'
    }
}

(2) If the super constructor supports it, adjust the property after having called the super constructor:

class BaseView extends Backbone.View {
    constructor() {
        super()
        this.tagName = 'div'
    }
}

(3) Otherwise, test if your property is already defined:

class BaseView extends Backbone.View {
    constructor() {
        if (this.tagName === undefined)
            this.tagName = 'div'
        super()
    }
}

But it is not considered good style to send implicit parameters to the super-constructor through properties of the instance being constructed. You smell it when you see references to this before the call to super(). At this point, it may be preferable to refactor the code and make all parameters explicit:

class BaseView extends Backbone.View {
    constructor(params = {}) {
        if (params.tagName === undefined)
            params.tagName = 'div'
        super(params)
    }
}