web-dev-qa-db-ja.com

ES2015で名前付き矢印関数を作成する方法

ES6で新しいarrowシンタックスに変換しようとしている関数があります。これは名前付き関数です。

function sayHello(name) {
    console.log(name + ' says hello');
}

Var文を使わずに名前を付ける方法はありますか。

var sayHello = (name) => {
    console.log(name + ' says hello');
}

明らかに、この関数は定義した後にしか使用できません。次のようなもの:

sayHello = (name) => {
        console.log(name + ' says hello');
    }

ES6にこれを行うための新しい方法はありますか?

178
jhamm

ES2015で名前付き矢印関数を作成する方法

あなたはあなたの質問であなたが除外した方法でそれをします:あなたは変数またはプロパティ名がJavaScriptエンジンによって名前として合理的に使用されることができる代入またはプロパティ初期化子の右側にそれを置きます。 otherそれを行う方法はありませんが、それを行うことは正しく、仕様で完全に網羅されています。

仕様によれば、この関数の名前はsayHelloです。

var sayHello = name => {
    console.log(name + ' says hello');
};

これは 代入演算子>実行時セマンティクス:評価 で定義されています 抽象SetFunctionName操作 (その呼び出しは現在ステップ1.eにあります。 iii)。

同様に、 実行時セマンティクス:PropertyDefinitionEvaluationSetFunctionNameを呼び出し、この関数に本当の名前を付けます。

let o = {
    sayHello: name => {
        console.log(`${name} says hello`);
    }
};

現代のエンジンはすでにそのようなステートメントのために関数の内部名を設定しました。 Edgeにはまだランタイムフラグの背後にある関数インスタンスのnameとして利用可能にするビットがあります。

たとえば、ChromeまたはFirefoxでは、Webコンソールを開いて次のスニペットを実行します。

"use strict";
let foo = () => { throw new Error(); };
console.log("foo.name is: " + foo.name);
try {
  foo();
} catch (e) {
  console.log(e.stack);
}

Chrome 51以上およびFirefox 53以上(および実験用フラグ付きのEdge 13以上)では、実行すると次のように表示されます。

 foo.nameは次のとおりです。foo 
 fooでのエラー
(http://stacksnippets.net/js:14:23)[http:// stacksnippets]での
 .net/js:17:3 

foo.name is: fooError...at fooに注意してください。

実験的フラグのないChrome 50以前、Firefox 52以前、およびEdgeでは、Function#nameプロパティをまだ持っていないため、代わりにこれが表示されます。

 foo.nameは次のとおりです。
 fooのエラー
(http://stacksnippets.net/js:14:23)[http:// stacksnippets]の
。 net/js:17:3 

名前がfoo.name is:から欠落していることに注意してください、しかしそれはスタックトレースに示されています。実際にnamepropertyを関数に実装することが、他のES2015の機能よりも優先度が低いということです。 ChromeとFirefoxは今それを持っています。エッジはそれを旗の後ろに持っています、おそらくそれは旗の後ろにずっと長くないでしょう。

明らかに、この関数は定義した後にしか使用できません

正しい。矢印関数には関数宣言構文はなく、関数構文だけであり、古いスタイルの名前付き関数式(var f = function foo() { };)の名前に相当する矢印はありません。だから、同等のものはありません:

console.log(function fact(n) {
    if (n < 0) {
        throw new Error("Not defined for negative numbers");
    }
    return n == 0 ? 1 : n * fact(n - 1);
}(5)); // 120

あなたはそれを二つの表現に分割しなければなりません(私はあなたがとにかくそうするべきだと主張します(とにかく

let fact = n => {
    if (n < 0) {
      throw new Error("Not defined for negative numbers.");
    }
    return n == 0 ? 1 : n * fact(n - 1);
};
console.log(fact(5));

もちろん、もし単一の式が必要なところにこれを置くためにあなたがhaveしているなら、あなたはいつでも...矢印関数を使うことができます。

console.log((() => {
    let fact = n => {
        if (n < 0) {
            throw new Error("Not defined for negative numbers.");
        }
        return n == 0 ? 1 : n * fact(n - 1);
    };
    return fact(5);
})()); // 120

私は言っているわけではない 'それはきれいだが、あなたが絶対に、積極的に単一の式のラッパーが必要な場合それは動作します。

179
T.J. Crowder

矢印の構文は、無名関数の短縮形です。無名関数は、匿名です。

名前付き関数はfunctionキーワードで定義されています。

86
Jörg W Mittag

'named'によって、あなたのarrow関数の.nameプロパティを設定したいということであれば、あなたは運がいいです。

代入式の右側に矢印関数が定義されている場合、エンジンは左側の名前を取り、それを使って矢印関数の.nameを設定します。

var sayHello = (name) => {
    console.log(name + ' says hello');
}

sayHello.name //=== 'sayHello'

とは言っても、あなたの質問はもっと '私は巻き上げるための矢印機能を手に入れることができますか?'のようです。それに対する答えは非常に古い「いいえ」です、私は怖いです。

44
hughfdjackson

これはES7で可能になるようです: https://babeljs.io/blog/2015/06/07/react-on-es6-plus#arrow-functions

例は次のとおりです。

class PostInfo extends React.Component {
  handleOptionsButtonClick = (e) => {
    this.setState({showOptionsModal: true});
  }
}

ES6の矢印関数の本体は、それを囲むコードと同じ字句的なthisを共有しています。これは、ES7プロパティの初期化子のスコープが限定されているためです。

これをbabelで動作させるには、最も実験的なES7のステージ0構文を有効にする必要があることに注意してください。私のwebpack.config.jsファイルでは、次のようにbabelローダーを更新しました。

{test: /\.js$/, exclude: /node_modules/, loader: 'babel?stage=0'},
0
Hamish Currie