1

I have found that keyword "this" is "undefined" until super() is called, and I'm wondering where this behavior documented. I'm asking only to learn where I can lookup these answers myself (in the future).

Code that shows this behavior is given below:

class BaseClass {
    constructor(){
        this.baseVar = 1;
    }
}

class SubClass extends BaseClass {
    constructor(...args){
        try {
            console.log('this BEFORE calling super.  this:', this);
        } catch(ex) {
            console.log('this BEFORE calling super. this: caused exception!');
        }
        super(...args);
        this.subVar = 2;
        console.log('this AFTER calling super.  this:', this);
    }
}

var base = new BaseClass();
var subclass = new SubClass();

The output from this is shown below:

this BEFORE calling super. this: caused exception!
this AFTER calling super.  this: SubClass { baseVar: 1, subVar: 2 }
ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
PatS
  • 8,833
  • 12
  • 57
  • 100
  • The exception gives you a message. Why are you catching and ignoring it? –  Dec 06 '17 at 18:40
  • As to where it's documented, it's in the same place that the entire language is documented... the language specification. –  Dec 06 '17 at 18:41
  • 1
    See the following for a better explanation as to *why* it's not allowed ["Uncaught ReferenceError: this is not defined" in class constructor](https://stackoverflow.com/questions/32516204/uncaught-referenceerror-this-is-not-defined-in-class-constructor) – JCOC611 Dec 06 '17 at 18:43
  • Every proper tutorial that explains subclassing and `super` should mention this. – Bergi Dec 06 '17 at 18:45
  • @rockstar, I was catching the error because I already knew it was saying "this" is undefined. In the question I said that "this" is undefined before calling super. I (perhaps incorrectly) thought it would make the question clearer. Sorry if it made it more confusing. – PatS Dec 06 '17 at 21:23

2 Answers2

2

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super

When used in a constructor, the super keyword appears alone and must be used before the this keyword is used. The super keyword can also be used to call functions on a parent object.

The example provided in the page showcases the behaviour you mentioned:

class Square extends Polygon {
  constructor(length) {
    this.height; // ReferenceError, super needs to be called first!

    // Here, it calls the parent class' constructor with lengths
    // provided for the Polygon's width and height
    super(length, length);

    // Note: In derived classes, super() must be called before you
    // can use 'this'. Leaving this out will cause a reference error.
    this.name = 'Square';
  }

  get area() {
    return this.height * this.width;
  }

  set area(value) {
    this.height = this.width = Math.sqrt(value);
  } 
}
Alberto Rivera
  • 3,652
  • 3
  • 19
  • 33
0

JavaScript's biggest problem currently is that debugging is harder compared to other languages as many things are dynamic and you can basically change the core concepts of how the language works. The main aim of ES6 was to get rid of common dynamic problems and missconceptions of the language. While prototypal Inheritance is really useful in some cases, the language architects saw a need for a better readable and more stable way of creating inheritance ( and more familar for java folks ). Thats why they introduced class, and that you can't work with thisbefore calling super() is one of the things to make it more stable.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151