o01
o01

Reputation: 5440

ES6 arrow functions trigger "'super' outside of function or class" error

Consider the following super class and sub class extending it:

class SuperClass {
    constructor(name){
        this.name = name;
    }

    sayName = () => {
        alert(this.name);
    }
}

class SubClass extends SuperClass {
    constructor(name){
        super(name);
    }

    sayName = () => {
        super.sayName();
        document.getElementsByTagName('body')[0].innerHTML = this.name;
    }
}

let B = new SubClass('Noam Chomsky');
B.sayName();

In this example the function sayName is written as an arrow function in both class definitions. And when I call B.sayName() I get an error saying:

'super' outside of function or class

JSFiddle demonstrating the error (Check the console)


However, if I re-write the class definitions to not use arrow functions, everything works fine and I do not get an error:

class SuperClass {
    constructor(name){
        this.name = name;
    }

    sayName() {
        alert(this.name);
    }
}

class SubClass extends SuperClass {
    constructor(name){
        super(name);
    }

    sayName() {
        super.sayName();
        document.getElementsByTagName('body')[0].innerHTML = this.name;
    }
}

let B = new SubClass('Noam Chomsky');
B.sayName();

JSFiddle demonstrating that it works fine

Can someone explain why I'm getting this error when I use arrow functions here?

Upvotes: 4

Views: 2517

Answers (2)

dhilt
dhilt

Reputation: 20744

The difference is that

sayName1 = () => {
    alert(this.name);
}

is a property with function type, while

sayName2() {
    alert(this.name);
}

is a method. And ES classes handle methods and properties in entirely different ways. Methods are existed on class prototype, while properties are being assigned to every instance. And you can't access parent's sayName1 via super.sayName1 due to it is not on your parent's class, it is only on instance object and could be accessed via instance.sayName1.

Also, from ECMAScript® 2015 Language Specification:

An ArrowFunction does not define local bindings for arguments, super, this, or new.target. Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment... An ArrowFunction that references super is always contained within a non-ArrowFunction and the necessary state to implement super is accessible via the scope that is captured by the function object of the ArrowFunction.

Upvotes: 6

Marco Principio
Marco Principio

Reputation: 495

As far as I understand, arrow functions act just like regular functions in most instances. However, when you are dealing with instances where the "this" keyword would come into play, the arrow function binds "this" to the context where it was defined. If you use a regular function you should have no problems.

Upvotes: 1

Related Questions