web-dev-qa-db-ja.com

ES6の矢印関数がプロトタイプで機能しませんか?

ES6 Arrow関数が、prototype.objectを使用してオブジェクトに関数を割り当てるときに機能しないように見える場合。次の例を検討してください。

function Animal(name, type){
 this.name = name;
  this.type = type;
  this.toString = () => `${this.name} is a ${this.type}`;

}
var myDog = new Animal('Max', 'Dog');
console.log(myDog.toString()); //Max is a Dog

オブジェクト定義で矢印関数を明示的に使用しても機能しますが、Object.prototype構文で矢印関数を使用しても機能しません。

function Animal2(name, type){
  this.name = name;
  this.type = type;
}
Animal2.prototype.toString = () => `${this.name} is a ${this.type}`;

var myPet2 = new Animal2('Noah', 'cat');
console.log(myPet2.toString()); //is a undefined

概念実証と同様に、Object.prototype構文でテンプレート文字列構文を使用しても機能します。

function Animal3(name, type){
  this.name = name;
  this.type = type;
}
Animal3.prototype.toString = function(){ return `${this.name} is a ${this.type}`;}

var myPet3 = new Animal3('Joey', 'Kangaroo');
console.log(myPet3.toString()); //Joey is a Kangaroo

明らかなものがないのですか?例2は論理的に機能するはずですが、出力に戸惑います。スコーピングの問題だと思いますが、「is un undefined」という出力が表示されます。

ES6フィドル

27
Jonathan Lucas

矢印関数は字句thisを提供します。関数の評価時に使用できるthisを使用します。

これは論理的には次のコードと同等です(thisという名前の変数を使用できないため、以下は有効なコードではありません)。

(function(this){
   // code that uses "this"
 })(this)

最初の例では、arrow関数はコンストラクター内にあり、thisは新しく生成されたインスタンスを指します。

3番目の例では、アロー関数は使用されず、標準のthis動作は通常どおり機能します(これは関数スコープ内で)。

2番目の例では、アロー関数を使用しますが、それが評価されるスコープでは、thisはグローバル/未定義です。

26
Amit

通常の関数は現在のJavaScriptオブジェクトへの参照を返しますが、矢印関数はグローバルウィンドウオブジェクトへの参照を返します。

通常の関数は、新しいキーワードを使用してオブジェクトを適切に処理します。それらには、オブジェクトの作成中に値を初期化できるconstructor関数があります。 プロトタイプチェーンを使用して管理できますが、矢印関数にはコンストラクター関数、プロトタイプチェーン。それらはオブジェクトでうまく機能していません。メモリを割り当てるための新しいキーワードと一緒に使用することはできません。

最初の例では、通常の関数内に矢印キー関数を記述して、出力を取得します。

function Animal2(name, type){
    this.name = name;
    this.type = type;
}
Animal2.prototype.toString = function(){
    return () => `${this.name} is a ${this.type}`;
}

var myPet2 = new Animal2('Noah', 'cat');
console.log(myPet2.toString()()); //Noah is a cat

参考: 通常の機能と矢印キー機能の違い

0