diff options
| author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
|---|---|---|
| committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
| commit | 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 (patch) | |
| tree | a9ef8ac1e1b8fe4207b6d64d3841bfb8990b6fd0 /files/zh-tw/web/javascript/reference/statements/function_star_ | |
| parent | 074785cea106179cb3305637055ab0a009ca74f2 (diff) | |
| download | translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.gz translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.bz2 translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.zip | |
initial commit
Diffstat (limited to 'files/zh-tw/web/javascript/reference/statements/function_star_')
| -rw-r--r-- | files/zh-tw/web/javascript/reference/statements/function_star_/index.html | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/files/zh-tw/web/javascript/reference/statements/function_star_/index.html b/files/zh-tw/web/javascript/reference/statements/function_star_/index.html new file mode 100644 index 0000000000..11b1013537 --- /dev/null +++ b/files/zh-tw/web/javascript/reference/statements/function_star_/index.html @@ -0,0 +1,207 @@ +--- +title: function* +slug: Web/JavaScript/Reference/Statements/function* +tags: + - ECMAScript 2015 + - Function + - Iterator + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/function* +--- +<div>{{jsSidebar("Statements")}}</div> + +<p><code><strong>function*</strong></code> 宣告式(<code>function</code> 關鍵字後面跟著一個星號)定義了一個<em>生成器函式(generator function)</em>,他會回傳一個{{jsxref("Global_Objects/Generator","生成器(Generator)")}}物件。</p> + +<div>{{EmbedInteractiveExample("pages/js/statement-functionasterisk.html")}}</div> + + + +<div class="noinclude"> +<p>你可以透過 {{jsxref("GeneratorFunction")}} 建構式來定義生成器函式。</p> +</div> + +<h2 id="語法">語法</h2> + +<pre class="syntaxbox">function* <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) { + <em>statements</em> +} +</pre> + +<dl> + <dt><code>name</code></dt> + <dd>函式名稱。</dd> +</dl> + +<dl> + <dt><code>param</code></dt> + <dd>要被傳入函式的引數名稱,一個函式最多可以擁有 255 個引數。</dd> +</dl> + +<dl> + <dt><code>statements</code></dt> + <dd>statements 構成了函式內容的陳述式。</dd> +</dl> + +<h2 id="描述">描述</h2> + +<p>生成器是可以離開後再次進入的函式。在兩次進入之間,生成器的執行狀態(變數綁定狀態)會被儲存。</p> + +<p>呼叫生成器函式並不會讓裡面的程式碼立即執行,而是會回傳一個針對該函式的<a href="/zh-TW/docs/Web/JavaScript/Reference/Iteration_protocols#iterator">迭代器(iterator)</a>物件。當呼叫迭代器的 <code>next()</code> 方法時,生成器函式將會執行到遭遇的第一個 {{jsxref("Operators/yield", "yield")}} 運算式,該運算式給定的值將從迭代器中回傳,如果是 {{jsxref("Operators/yield*", "yield*")}} 則會交給另一個生成器函式處理。<code>next()</code> 方法回傳一個物件,該物件有 <code>value</code> 屬性,包含了產生的數值,還有 <code>done</code> 屬性,為布林值,指出該生成器是否產出最後的數值。呼叫 <code>next()</code> 方法如果帶有一個參數,將會讓先前暫停的生成器函式恢復執行,以該參數值取代先前暫停的 <code>yield</code> 陳述式。</p> + +<p>生成器中的 <code>return</code> 陳述式被執行時,會讓生成器 <code>done</code> 狀態為真。若有數值被返回的動作帶回,將是放在 <code>value</code> 傳回的。已返回的生成器不會再產生任何數值。</p> + +<h2 id="範例">範例</h2> + +<h3 id="簡單例子">簡單例子</h3> + +<pre class="brush: js">function* idMaker() { + var index = 0; + while (index < index+1) + yield index++; +} + +var gen = idMaker(); + +console.log(gen.next().value); // 0 +console.log(gen.next().value); // 1 +console.log(gen.next().value); // 2 +console.log(gen.next().value); // 3 +// ...</pre> + +<h3 id="yield*_的範例">yield* 的範例</h3> + +<pre class="brush: js">function* anotherGenerator(i) { + yield i + 1; + yield i + 2; + yield i + 3; +} + +function* generator(i) { + yield i; + yield* anotherGenerator(i); + yield i + 10; +} + +var gen = generator(10); + +console.log(gen.next().value); // 10 +console.log(gen.next().value); // 11 +console.log(gen.next().value); // 12 +console.log(gen.next().value); // 13 +console.log(gen.next().value); // 20 +</pre> + +<h3 id="傳入引數至生成器">傳入引數至生成器</h3> + +<pre class="brush: js">function* logGenerator() { + console.log(0); + console.log(1, yield); + console.log(2, yield); + console.log(3, yield); +} + +var gen = logGenerator(); + +// the first call of next executes from the start of the function +// until the first yield statement +gen.next(); // 0 +gen.next('pretzel'); // 1 pretzel +gen.next('california'); // 2 california +gen.next('mayonnaise'); // 3 mayonnaise +</pre> + +<h3 id="生成器中的回傳陳述式">生成器中的回傳陳述式</h3> + +<pre class="brush: js">function* yieldAndReturn() { + yield "Y"; + return "R"; + yield "unreachable"; +} + +var gen = yieldAndReturn() +console.log(gen.next()); // { value: "Y", done: false } +console.log(gen.next()); // { value: "R", done: true } +console.log(gen.next()); // { value: undefined, done: true } +</pre> + +<h3 id="生成器無法被建構">生成器無法被建構</h3> + +<pre class="brush: js example-bad">function* f() {} +var obj = new f; // throws "TypeError: f is not a constructor"</pre> + +<h3 id="以表達式定義生成器">以表達式定義生成器</h3> + +<pre><code>const foo = function* () { yield 10; yield 20; }; +const bar = foo();console.log(bar.next()); // {value: 10, done: false}</code></pre> + +<p> </p> + +<h2 id="規範">規範</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ES2015', '#', 'function*')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ES2016', '#', 'function*')}}</td> + <td>{{Spec2('ES2016')}}</td> + <td>Changed that generators should not have [[Construct]] trap and will throw when used with <code>new</code>.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#', 'function*')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="瀏覽器相容性">瀏覽器相容性</h2> + +<div> + + +<p>{{Compat("javascript.statements.generator_function")}}</p> +</div> + +<h2 id="Firefox_規範註記">Firefox 規範註記</h2> + +<h4 id="Generators_and_iterators_in_Firefox_versions_before_26">Generators and iterators in Firefox versions before 26</h4> + +<p>Older Firefox versions implement an older version of the generators proposal. In the older version, generators were defined using a regular <code>function</code> keyword (without an asterisk) among other differences. See <a href="/en-US/docs/Web/JavaScript/Reference/Statements/Legacy_generator_function">Legacy generator function </a>for further information.</p> + +<h4 id="IteratorResult_object_returned_instead_of_throwing"><code>IteratorResult</code> object returned instead of throwing</h4> + +<p>Starting with Gecko 29 {{geckoRelease(29)}}, the completed generator function no longer throws a {{jsxref("TypeError")}} "generator has already finished". Instead, it returns an <code>IteratorResult</code> object like <code>{ value: undefined, done: true }</code> ({{bug(958951)}}).</p> + +<h2 id="參見">參見</h2> + +<ul> + <li>{{jsxref("Operators/function*", "function* expression")}}</li> + <li>{{jsxref("GeneratorFunction")}} object</li> + <li><a href="/zh-TW/docs/Web/JavaScript/Reference/Iteration_protocols">迭代協議</a></li> + <li>{{jsxref("Operators/yield", "yield")}}</li> + <li>{{jsxref("Operators/yield*", "yield*")}}</li> + <li>{{jsxref("Function")}} object</li> + <li>{{jsxref("Statements/function", "function declaration")}}</li> + <li>{{jsxref("Operators/function", "function expression")}}</li> + <li>{{jsxref("Functions_and_function_scope", "Functions and function scope")}}</li> + <li>Other web resources: + <ul> + <li><a href="http://facebook.github.io/regenerator/">Regenerator</a> an ES2015 generator compiler to ES5</li> + <li><a href="http://www.youtube.com/watch?v=qbKWsbJ76-s">Forbes Lindesay: Promises and Generators: control flow utopia -- JSConf EU 2013</a></li> + <li><a href="https://github.com/mozilla/task.js">Task.js</a></li> + <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/master/async%20%26%20performance/ch4.md#iterating-generators-asynchronously">Iterating generators asynchronously</a></li> + </ul> + </li> +</ul> |
