--- title: function* slug: Web/JavaScript/Reference/Statements/function* translation_of: Web/JavaScript/Reference/Statements/function* ---
Khai báo function*
(từ khóa function
tiếp theo là dấu sao) định nghĩa một generator function, một phương thức trả về đối tượng {{jsxref("Global_Objects/Generator","Generator")}}.
Bạn cũng có thể khai báo generator functions bằng constructor {{jsxref("GeneratorFunction")}} , hoặc cú pháp function expression.
function* name([param[, param[, ... param]]]) { statements }
name
param
statements
Generators là một hàm có thể thoát và sau đó gọi lại lần nữa. Giá trị của biến trong các lần gọi được lưu lại trong các lần gọi tiếp theo.
Pattern là cách hàm async
được viết ra.
Gọi một generator function không thực thi các lệnh bên trong hàm ngày lập tức; Thay vào đó, một object iterator được trả về. Khi iterator gọi đến phương thức next()
, lúc này các lệnh bên trong hàm được thực thi cho đến khi gặp câu {{jsxref("Operators/yield", "yield")}} , sau câu lệnh {{jsxref("Operators/yield", "yield")}} là giá trị sẽ trả về, hoặc gọi đến một generator function khác. Phương thức next()
trả về một object với property value
chứa giá trị yielded và property done
, giá trị kiểu boolean, xác định generator yielded trả về đã là cuối cùng chưa. Gọi phương thức next()
với một tham số sẽ chạy hàm generator tiếp tục, thay thế câu yield
nơi hàm đã dừng lại trước đó với tham số từ next()
.
Câu lệnh return
trong generator, khi chạy, sẽ kết thúc generator (ví dụ property done
trả về sẽ có giá trị true
). Nếu giá trị đã được trả về, nó sẽ được set cho property value
.
Giống như câu lệnh return
, thrown error trong generator sẽ kết thúc generator -- trừ khi bắt lại bằng bên trong generator.
Khi một generator kết thúc, các câu gọi next
tiếp theo sau sẽ không được thực thi, nó chỉ trả về object có dạng: {value: undefined, done: true}
.
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 // ...
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
function* logGenerator() { console.log(0); console.log(1, yield); console.log(2, yield); console.log(3, yield); } var gen = logGenerator(); gen.next(); // 0 gen.next('pretzel'); // 1 pretzel gen.next('california'); // 2 california gen.next('mayonnaise'); // 3 mayonnaise
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 }
function* f() {} var obj = new f; // throws "TypeError: f is not a constructor
const foo = function* () { yield 10; yield 20; }; const bar = foo(); console.log(bar.next()); // {value: 10, done: false}
Specification | Status | Comment |
---|---|---|
{{SpecName('ES2015', '#sec-generator-function-definitions', 'function*')}} | {{Spec2('ES2015')}} | Initial definition. |
{{SpecName('ES2016', '#sec-generator-function-definitions', 'function*')}} | {{Spec2('ES2016')}} | Changed that generators should not have [[Construct]] trap and will throw when used with new . |
{{SpecName('ESDraft', '#sec-generator-function-definitions', 'function*')}} | {{Spec2('ESDraft')}} |
{{Compat("javascript.statements.generator_function")}}
Older Firefox versions implement an older version of the generators proposal. In the older version, generators were defined using a regular function
keyword (without an asterisk) among other differences. See Legacy generator function for further information.
IteratorResult
object returned instead of throwingStarting with Gecko 29 {{geckoRelease(29)}}, the completed generator function no longer throws a {{jsxref("TypeError")}} "generator has already finished". Instead, it returns an IteratorResult
object like { value: undefined, done: true }
({{bug(958951)}}).