254

このページで新しい JavaScript 関数タイプを見つけました。

// NOTE: "function*" is not supported yet in Firefox.
// Remove the asterisk in order for this code to work in Firefox 13 

function* fibonacci() { // !!! this is the interesting line !!!
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield curr;
    }
}

私はすでに何を知っていてyield、何をするのかを知っていますがlet[?,?]=[?,?]、それが何function*を意味するのかわかりません。それは何ですか?

PS わざわざ Google を試す必要はありません。アスタリスクを含む式を検索することはできません (プレースホルダーとして使用されます)。

4

4 に答える 4

210

ジェネレーター関数です。

ジェネレーターは、終了して後で再入力できる関数です。それらのコンテキスト (変数バインディング) は、再入口間で保存されます。

ジェネレーター関数を呼び出しても、その本体はすぐには実行されません。代わりに、関数の iterator オブジェクトが返されます。イテレータのメソッドが呼び出されると、イテレータから返される値を指定するnext()最初の式までジェネレータ関数の本体が実行されるか、または を使用して別のジェネレータ関数に委任されます。yieldyield*


歴史的なメモ:

の提案された構文ですEcmaScript.next

Mozilla の Dave Herman がEcmaScript.nextについて講演しました。30:15で彼は発電機について話します。

彼は以前、Mozilla がどのように委員会の舵取りを助けるために提案された言語変更を実験的に実装しているかを説明しました。Dave は、Mozilla の CTO (だと思います) であり、元の JavaScript デザイナーである Brendan Eich と緊密に協力しています。

EcmaScript ワーキング グループ wiki で詳細を確認できます: http://wiki.ecmascript.org/doku.php?id=harmony:generators

ワーキング グループ (TC-39) は、EcmaScript.next に何らかのジェネレータ イテレータの提案が必要であるという一般的な合意を得ていますが、これは最終的なものではありません。

言語の次のバージョンで変更なしにこれが表示されることに依存するべきではありません。変更されなくても、おそらくしばらくの間、他のブラウザで広く表示されることはありません.

概要

中断された実行コンテキスト (つまり、関数のアクティブ化) をカプセル化するオブジェクトとして表される、ファーストクラスのコルーチン。先行技術: Python、Icon、Lua、Scheme、Smalltalk。

フィボナッチ数列の「無限」数列 (2 53付近の動作にもかかわらず):

function* fibonacci() {
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield curr;
    }
}

ジェネレーターはループで繰り返すことができます:

for (n of fibonacci()) {
    // truncate the sequence at 1000
    if (n > 1000)
        break;
    print(n);
}

ジェネレーターはイテレーターです:

let seq = fibonacci();
print(seq.next()); // 1
print(seq.next()); // 2
print(seq.next()); // 3
print(seq.next()); // 5
print(seq.next()); // 8
于 2012-03-08T16:02:47.430 に答える
52

これはジェネレーター関数です-引用したページで、「これは興味深い行です」に置き換えたコメントでそう言っています...

基本的には、プログラムでシーケンスを指定して、事前にシーケンス全体 (おそらく無限のサイズ) を計算しなくても、シーケンスを渡したり、インデックスによって要素にアクセスしたりできるようにする方法です。

于 2012-03-08T16:08:50.950 に答える
11

このfunction*型は、反復可能なプロセスのジェネレーター関数として機能するように見えます。C# には「yield return」を使用したこのような機能があります。12 を参照してください。

基本的に、これは、この関数を繰り返しているものに各値を 1 つずつ返します。これが、ユースケースが foreach スタイルのループでそれを示している理由です。

于 2012-03-08T16:04:36.147 に答える