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

Consider the following super class and sub class extending it:class SuperClass {constructor(name){this.

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?

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?

Share Improve this question edited Oct 22, 2017 at 0:56 o01 asked Oct 22, 2017 at 0:51 o01o01 5,45012 gold badges48 silver badges87 bronze badges 4
  • why do you want to define sayName as an arrow function in the first place? sayName = () => { alert(this.name); } syntax is not even standard yet (it's currently stage 2) – Jaromanda X Commented Oct 22, 2017 at 2:42
  • 2 There might be an issue with the Babel version jsfiddle is using. As one of the answers said, calling super.sayName() wouldn't work anyway because there is no sayName method on SuperClass.prototype. However, referencing super inside the SubClass' sayName method should work. After all, the code is the same as (note that I made sayName a proper method in SuperClass): jsfiddle/5y9bqwd0 – Felix Kling Commented Oct 22, 2017 at 3:05
  • And here is another option for child arrow function property: jsfiddle/zoeh5bp2. Bot of them are about closuring super from constructor. – dhilt Commented Oct 22, 2017 at 3:25
  • @FelixKling An earlier answer to this question referenced this bug report for Babel: github./babel/babel/issues/3930#issuement-245408381, explaining that the issue is linked to generators not being able to call super. – o01 Commented Oct 22, 2017 at 11:40
Add a ment  | 

2 Answers 2

Reset to default 6

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.

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 e 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.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745347786a4623643.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信