function* 宣è¨
Baseline
Widely available
This feature is well established and works across many devices and browser versions. Itâs been available across browsers since 2016å¹´9æ.
function* 宣è¨ã¯ãæ°ããã¸ã§ãã¬ã¼ã¿ã¼é¢æ°ãæå®ãããååã¸ã®ãã¤ã³ãã¨ãã¦ä½æãã¾ããã¸ã§ãã¬ã¼ã¿ã¼é¢æ°ã¯ãè±åºããå¾ã§ãã®ã³ã³ããã¹ãï¼å¤æ°ã®ãã¤ã³ãï¼ãä¿åããã¾ã¾åå
¥ãããã¨ãå¯è½ã§ãã
ã¸ã§ãã¬ã¼ã¿ã¼é¢æ°ã¯ function* å¼ã使ã£ã¦å®ç¾©ãããã¨ãã§ãã¾ãã
試ãã¦ã¿ã¾ããã
function* generator(i) {
yield i;
yield i + 10;
}
const gen = generator(10);
console.log(gen.next().value);
// äºæ³ãããçµæ: 10
console.log(gen.next().value);
// äºæ³ãããçµæ: 20
æ§æ
function* name(param0) {
statements
}
function* name(param0, param1) {
statements
}
function* name(param0, param1, /* â¦, */ paramN) {
statements
}
ã¡ã¢: ã¸ã§ãã¬ã¼ã¿ã¼é¢æ°ã«ã¯ã対å¿ããã¢ãã¼é¢æ°ã¯ããã¾ããã
ã¡ã¢:
function 㨠* ã¯å¥ã
ãªãã¼ã¯ã³ãªã®ã§ããã¯ã¤ãã¹ãã¼ã¹ã¾ãã¯æ¹è¡ã§åºåããã¨ãå¯è½ã§ãã
弿°
name-
颿°åã
paramçç¥å¯-
颿°ã®å½¢å¼ä¸ã®å¼æ°ã®ååã弿°ã®æ§æã«ã¤ãã¦ã¯ã颿°ãªãã¡ã¬ã³ã¹ãåç §ãã¦ãã ããã
statementsçç¥å¯-
颿°ã®æ¬ä½ãæ§æããæã
解説
function* 宣è¨ã¯ GeneratorFunction ãªãã¸ã§ã¯ããçæãã¾ããã¸ã§ãã¬ã¼ã¿ã¼é¢æ°ãå¼ã³åºããããã³ã«ãæ°ãã Generator ãªãã¸ã§ã¯ããè¿ãããããã¯ã¤ãã¬ã¼ã¿ã¼ãããã³ã«ã«æºæ ãã¾ããã¸ã§ãã¬ã¼ã¿ã¼é¢æ°ã®å®è¡ã¯ãããå ´æã§ä¸æããã¾ããåæç¶æ
ã§ã¯é¢æ°æ¬ä½ã®å
é ã§ä¸æããã¾ããã¸ã§ãã¬ã¼ã¿ã¼é¢æ°ã¯è¤æ°åå¼ã³åºãã¦è¤æ°ã®ã¸ã§ãã¬ã¼ã¿ã¼ãåæã«çæã§ãã¾ããåã¸ã§ãã¬ã¼ã¿ã¼ã¯ãã¸ã§ãã¬ã¼ã¿ã¼é¢æ°ã®å®è¡ã³ã³ããã¹ããç¬èªã«ä¿æããç¬ç«ãã¦ã¹ãããå®è¡ã§ãã¾ãã
ã¸ã§ãã¬ã¼ã¿ã¼ã¯åæ¹åã®å¶å¾¡ããã¼ããããã¨ãã§ãã¾ããå¶å¾¡ããã¼ã¯ã¸ã§ãã¬ã¼ã¿ã¼é¢æ°ï¼å¼ã³åºãå
ï¼ã¨ãã®å¼ã³åºãå´ã®éã§ãåæ¹ãæãåæ°ã ãç§»è¡ã§ãã¾ããå¶å¾¡ããã¼ã¯å¼ã³åºãå´ããå¼ã³åºãå
ã¸ãã¸ã§ãã¬ã¼ã¿ã¼ã®ã¡ã½ãããnext()ãthrow()ãreturn() ãå¼ãã§ç§»è¡ãã¾ããå¶å¾¡ããã¼ã¯ãreturn ã throw ã使ç¨ãã¦é常éã颿°ãçµäºããããããã¹ã¦ã®æãå®è¡ããããyield ããã³ yield* å¼ã使ç¨ããããããã¨ã§ãå¼ã³åºãå´ããå¼ã³åºãå
ã¸é²ããã¨ãã§ãã¾ãã
ã¸ã§ãã¬ã¼ã¿ã¼ã® next() ã¡ã½ãããå¼ã³åºãããã¨ãã¸ã§ãã¬ã¼ã¿ã¼é¢æ°ã®æ¬ä½ã¯æ¬¡ã®ããããã«ãªãã¾ã§å®è¡ããã¾ãã
yieldå¼ããã®å ´åãnext()ã¡ã½ããã¯ãyield ã§è¿ãããå¤ãå«ãvalueããããã£ã¨ã常ã«falseã§ããdoneããããã£ãæã¤ãªãã¸ã§ã¯ããè¿ãã¾ããæ¬¡ã«next()ãå¼ã³åºãããã¨ãyieldå¼ã¯next()ã«æ¸¡ãããå¤ã«è©ä¾¡ããã¾ãã- å¥ã®ã¤ãã¬ã¼ã¿ã¼ã«å§è²ãã
yield*æ¼ç®åããã®å ´åãã¸ã§ãã¬ã¼ã¿ã¼ã«å¯¾ãããã®å¼ã³åºãããã³ä»¥éã®next()å¼ã³åºãã¯ãå§è²å ã®ã¤ãã¬ã¼ã¿ã¼ãå®äºããã¾ã§ãå§è²å ã®ã¤ãã¬ã¼ã¿ã¼ã«å¯¾ããnext()å¼ã³åºãã¨åçã¨ãªãã¾ãã returnæï¼try...catch...finallyã§ä»å ¥ãããªããã®ï¼ãã¾ãã¯å¶å¾¡ããã¼ã®çµããï¼æé»çã«return undefinedãæå³ãã¾ãï¼ããã®å ´åãã¸ã§ãã¬ã¼ã¿ã¼ã¯å®äºããnext()ã¡ã½ããã¯è¿å¤ãå«ãvalueããããã£ã¨å¸¸ã«trueã¨ãªãdoneããããã£ãæã¤ãªãã¸ã§ã¯ããè¿ãã¾ãã以éã®next()å¼ã³åºãã¯å¹æãæããã常ã«{ value: undefined, done: true }ãè¿ãã¾ãã- 颿°å
ã§çºçããã¨ã©ã¼ï¼
throwæã¾ãã¯æªå¦çã®ä¾å¤ã«ããï¼ãnext()ã¡ã½ããããã®ã¨ã©ã¼ãçºçãããã¸ã§ãã¬ã¼ã¿ã¯å®äºããã以éã®next()å¼ã³åºãã¯å¹æãªãã常ã«{ value: undefined, done: true }ãè¿ãã
ã¸ã§ãã¬ã¼ã¿ã¼ã® throw() ã¡ã½ãããå¼ã³åºãããã¨ãç¾å¨ã®ä¸æä½ç½®ã§ã¸ã§ãã¬ã¼ã¿ã¼ã®æ¬ä½ã« throw æãæ¿å
¥ããããã®ããã«åä½ãã¾ããåæ§ã«ãã¸ã§ãã¬ã¼ã¿ã¼ã® return() ã¡ã½ãããå¼ã³åºãããã¨ãç¾å¨ã®ä¸æä½ç½®ã« return æãæ¿å
¥ããããã®ããã«åä½ãã¾ããã©ã¡ãã®ã¡ã½ããããã¸ã§ãã¬ã¼ã¿ã¼é¢æ°ã try...catch...finally ã«ãã£ã¦å®äºããã£ããããªãéããé常ã¯ã¸ã§ãã¬ã¼ã¿ã¼ãå®äºããã¾ãã
ã¸ã§ãã¬ã¼ã¿ã¼ã¯ãã¤ã¦éåæããã°ã©ãã³ã°ã®ãã©ãã¤ã ã§ãããã³ã¼ã«ããã¯å°çãå¶å¾¡ã®å転ã«ãã£ã¦é¿ãããã¨ãã§ãã¾ãããç¾å¨ã§ã¯ããã®å ´åã®è§£æ±ºã¯ããã·ã³ãã«ãª async 颿°ã¢ãã«ã¨ Promise ãªãã¸ã§ã¯ãã§è§£æ±ºããã¦ãã¾ããããããã¸ã§ãã¬ã¼ã¿ã¼ã¯ä¾ç¶ã¨ãã¦ä»ã®å¤ãã®ã¿ã¹ã¯ãä¾ãã°ã¤ãã¬ã¼ã¿ã¼ãç´æçã«å®ç¾©ããã¨ãã£ãç¨éã§æç¨ã§ãã
function* 宣è¨ã¯ function 宣è¨ã¨åæ§ã®æåã示ãã¾ãããããã¯ã¹ã³ã¼ãã®å
é ã«å·»ãä¸ãããããã®ã¹ã³ã¼ãå
ã®ã©ãã§ãå¼ã³åºãã¾ããã¾ããç¹å®ã®ã³ã³ããã¹ãã§ã®ã¿å宣è¨ãå¯è½ã§ãã
ä¾
>åºæ¬çãªä¾
function* idMaker() {
let index = 0;
while (true) {
yield index++;
}
}
const 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
// â¦
yield* ã使ç¨ããä¾
function* anotherGenerator(i) {
yield i + 1;
yield i + 2;
yield i + 3;
}
function* generator(i) {
yield i;
yield* anotherGenerator(i);
yield i + 10;
}
const 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);
}
const gen = logGenerator();
// æåã® next ã®å¼ã³åºãã§ã颿°ã®æåããã
// æåã® yield æã®åã¾ã§å®è¡ãããã
gen.next(); // 0
gen.next("pretzel"); // 1 pretzel
gen.next("california"); // 2 california
gen.next("mayonnaise"); // 3 mayonnaise
ã¸ã§ãã¬ã¼ã¿ã¼ã«ããã return æ
function* yieldAndReturn() {
yield "Y";
return "R";
yield "unreachable";
}
const 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 }
ãªãã¸ã§ã¯ãããããã£ã¨ãã¦ã®ã¸ã§ãã¬ã¼ã¿ã¼
const someObj = {
*generator() {
yield "a";
yield "b";
},
};
const gen = someObj.generator();
console.log(gen.next()); // { value: 'a', done: false }
console.log(gen.next()); // { value: 'b', done: false }
console.log(gen.next()); // { value: undefined, done: true }
ãªãã¸ã§ã¯ãã¡ã½ããã¨ãã¦ã®ã¸ã§ãã¬ã¼ã¿ã¼
class Foo {
*generator() {
yield 1;
yield 2;
yield 3;
}
}
const f = new Foo();
const gen = f.generator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
è¨ç®ããããã£ã¨ãã¦ã®ã¸ã§ãã¬ã¼ã¿ã¼
class Foo {
*[Symbol.iterator]() {
yield 1;
yield 2;
}
}
const SomeObj = {
*[Symbol.iterator]() {
yield "a";
yield "b";
},
};
console.log(Array.from(new Foo())); // [ 1, 2 ]
console.log(Array.from(SomeObj)); // [ 'a', 'b' ]
ã¸ã§ãã¬ã¼ã¿ã¼ã¯ã³ã³ã¹ãã©ã¯ã¿ã¼ã§ã¯ãªã
function* f() {}
const obj = new f(); // throws "TypeError: f is not a constructor
ã¸ã§ãã¬ã¼ã¿ã¼ã®ä¾
function* powers(n) {
// çæã®ç¡éã«ã¼ã
for (let current = n; ; current *= n) {
yield current;
}
}
for (const power of powers(2)) {
// ã¸ã§ãã¬ã¼ã¿ã¼ãå¶å¾¡
if (power > 32) {
break;
}
console.log(power);
// 2
// 4
// 8
// 16
// 32
}
仿§æ¸
| Specification |
|---|
| ECMAScript® 2027 Language Specification> # sec-generator-function-definitions> |
ãã©ã¦ã¶ã¼ã®äºææ§
é¢é£æ å ±
- 颿°ã¬ã¤ã
- ã¤ãã¬ã¼ã¿ã¼ã¨ã¸ã§ãã¬ã¼ã¿ã¼ã¬ã¤ã
- 颿°
GeneratorFunctionfunction*å¼functionasync functionasync function*- å復å¦çãããã³ã«
yieldyield*Generator- Regenerator - GitHub
- Promises and Generators: control flow utopia presentation by Forbes Lindesay at JSConf (2013)
- Task.js on GitHub
- You Don't Know JS: Async & Performance, Ch.4: Generators by Kyle Simpson