2017-10-22 10 views
0

に延びる以下スーパークラスとサブクラスを検討:ES6矢印機能トリガ「『スーパー』外部関数又はクラスの」エラー

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(); 

この例では関数sayNameが両方の矢印の関数として書かれていますクラス定義。私が言って、私はエラーを取得B.sayName()を呼び出すときに:

'super' outside of function or class

JSFiddle demonstrating the 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

:と私はエラーを取得しません10

ここで矢印機能を使用すると、なぜこのエラーが発生するのか説明できますか?

+0

あなたが最初の場所で、矢印関数として 'sayName'を定義したいなぜ? 'sayName =()=> { アラート(this.name); } '構文はまだ標準化されていません(現在2段階目です)。 –

+2

jsfiddleが使用しているBabelのバージョンに問題がある可能性があります。答えの一つとして、 'SuperClass.prototype'に' sayName'メソッドがないので、 'super.sayName()'を呼び出すことはできません。 **しかし、**、SubClassの 'sayName'メソッドの中の' super'を参照すると動作するはずです。結局のところ、コードは次のようになります( 'SuperClass'で' sayName'を適切なメソッドにしたことに注意してください):https://jsfiddle.net/5y9bqwd0/ –

+0

そして、ここでは子矢印関数のプロパティの別のオプションがあります:https: //jsfiddle.net/zoeh5bp2/。それらのボットはコンストラクタから 'super'を閉じることです。 – dhilt

答えて

2

差が

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

の方法である

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

は、関数型のプロパティであることです。また、ESクラスはメソッドとプロパティを全く異なる方法で処理します。メソッドはクラスプロトタイプに存在し、プロパティはすべてのインスタンスに割り当てられます。 super.sayName1を経由して親のsayName1にアクセスすることはできません。これは親クラスにないため、インスタンスオブジェクト上にあり、instance.sayName1でアクセスできます。 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.

+1

* "親のクラスにないため、親の' sayName1'に 'super.sayName1'を介してアクセスすることはできません" *正しいですが、違うエラーになります。OPは矢印関数内で 'super 'を参照することさえできないようですが、コンストラクタ内で関数を割り当てるための文法的な砂糖なので、IMOを動作させるはずです。 –

+0

バベルのバグが特定のエラーのように見えるにもかかわらず、ここで矢印機能を使用しない理由が説明されているので、これを答えとして受け入れるつもりです(上記のコメントを参照)。 – o01

1

私が理解する限り、矢印の機能はほとんどの場合通常の機能と同じように機能します。ただし、 "this"キーワードが有効になるインスタンスを扱う場合、矢印関数は "this"を定義したコンテキストにバインドします。通常の関数を使用する場合、問題はありません。

+0

console.logを試してみてください。 superClassとsubClassの両方で、あなたは私が何を意味するのか見るでしょう。 –

+1

これはOPの問題と何が関係していますか? –

関連する問題