ãããŸã§äœåºŠãåºãŠããå埩å¯èœ (iterable) ãšå埩å (iterator) ã®ã話ã§ãããã£ãšã
å ã«ãŸãšã
- Iterableãªããžã§ã¯ãã¯
- Iteratorãè¿ãã¡ãœãã
[Symbol.iterator]
ãæ〠for-of
ã§äœ¿ãã
- Iteratorãè¿ãã¡ãœãã
- Iteratorãªããžã§ã¯ãã¯
- IteratorResultãè¿ãã¡ãœãã
next()
ãæã€
- IteratorResultãè¿ãã¡ãœãã
- IteratorResultãªããžã§ã¯ãã¯
- ããããã£
done
,value
ãæã€
- ããããã£
- é
åã¯
- Iterableã§ãã
- Iteratorã§ã¯ãªã
arr.values()
ã¯- Iterableã§ãã
- Iteratorã§ãã
- Generatorãªããžã§ã¯ãã¯
- Iterableã§ããããã€Iteratorã§ãã
- Generatoré¢æ°ã¯
function*(){}
ã®ãã€- Generatorãªããžã§ã¯ããè¿ã
èªäœäŸ
// Iteratorã¯next()ãæ〠class MyIterator { constructor () { this.index = 0; this.values = [11, 22, 33]; } next () { const value = this.values[this.index]; this.index += 1; const result = { done: !value, value }; return result; } } // Iterableã¯[Symbol.iterator]()ãæ〠class MyIterable { [Symbol.iterator] () { return new MyIterator(); } } const iterable = new MyIterable(); for (const value of iterable) { console.log(value); } // 11 // 22 // 33
å埩 (iteration)
IterableãšIteratorã¯ãå®åšããã³ã³ã¹ãã©ã¯ã¿ãŒã§ã¯ãªãæŠå¿µçãªãã€ã³ã¿ãŒãã§ã€ã¹ããšããŠå®çŸ©ãããŠããŸããä»æ§ã ãã瀺ãããŠããããæºããã°ãããã¯Iterableã§ããããšããªããšãèšã£ãŠè¯ããšããããšã§ãã
ä»æ§æžã®Iterationã®ç« ã¯ãã€ã³ã¿ãŒãã§ã€ã¹ã«ã€ããŠã®èª¬æããå§ãŸããŸãã
An interface is a set of property keys whose associated values match a specific specification. Any object that provides all the properties as described by an interface’s specification conforms to that interface. An interface is not represented by a distinct object. There may be many separately implemented objects that conform to any interface. An individual object may conform to multiple interfaces.
- ã€ã³ã¿ãŒãã§ã€ã¹ãšã¯ãé¢é£ããå€ãç¹å®ã®ä»æ§ã«åèŽããããããã£ããŒã®çµã¿åããã§ããã
- ã€ã³ã¿ãŒãã§ã€ã¹ã®ä»æ§ã§è¿°ã¹ããããã¹ãŠã®ããããã£ãæäŸãããããããªããžã§ã¯ãã¯ããã®ã€ã³ã¿ãŒãã§ã€ã¹ã«æºæ ããŠããã
- ã€ã³ã¿ãŒãã§ã€ã¹ã¯åå¥ã®ãªããžã§ã¯ããšããŠã¯ååšããªãã
- ããã€ã³ã¿ãŒãã§ã€ã¹ã«æºæ ãããå¥ã ã«å®è£ ãããŠããè€æ°ã®ãªããžã§ã¯ãããã£ãŠãããã
- åã ã®ãªããžã§ã¯ããè€æ°ã®ã€ã³ã¿ãŒãã§ã€ã¹ã«æºæ ããŠãããã
ïŒâ»èš³æ³š: åæã«1æããšã«ç®æ¡æžããžå€æããŸãããå 容ã¯ãã®ãŸãŸãïŒ
ã¡ãªã¿ã« isIterable()
ã isIterator()
ã®ãããªãã®ã¯ä»æ§ã«ã¯ãããŸããããŸãã¡ãœããå®è¡ããŠæ»ãå€ãæ£ããããšãŸã§ç¢ºèªããªããšãããªãã®ã§ãJavaScriptã§ç¶ºéºã«ã€ããã®ã¯ã¡ãã£ãšé£ããã£ãããã
å®çŸ©ãããŠããã€ã³ã¿ãŒãã§ã€ã¹
5çš®ãããŸãã
- å埩å¯èœ Iterable
- å埩å Iterator
- éåæå埩å¯èœ AsyncIterable
- éåæå埩å AsyncIterator
- å埩çµæ IteratorResult
å埩å¯èœ (Iterable)
[Symbol.iterator]()
ã¡ãœãããå埩åãè¿ããã®ã
for-of
ã§äœ¿ãããã€ãé
åãšãã Set
ãšããé
åãšããæååãšããããšé
åãšãã
ä»æ§ãçãã
Property Value Requirements @@iterator
A function that returns an Iterator object. The returned object must conform to the Iterator interface.
ãããã㣠| å€ | èŠæ± |
---|---|---|
@@iterator |
Iterator ãªããžã§ã¯ããè¿ãé¢æ°ã | è¿åŽããããªããžã§ã¯ã㯠Iterator ã€ã³ã¿ãŒãã§ã€ã¹ã«æºæ ããªããã°ãªããªãã |
[Symbol.iterator]()
ã¡ãœãã
ä»æ§æžã§ã¯ @@iterator
ãšãã圢ã§è¡šçŸãããååã®ã¡ãœããã§ããç¹å¥ãªãã®ãªã®ã§ãååãæååã§ã¯ãªãã·ã³ãã«ã«ãªã£ãŠããŸããç¥ãããã©ã
ãã® [Symbol.iterator]()
ãšããååã§Iteratorãè¿ããªããžã§ã¯ããIterableãšåŒã¹ããšãã話ã ãã©ããã以å€ã®ã¡ãœãããIteratorãè¿ãã®ã¯èªç±ã§ããäŸãã°é
åã¯ãã® [Symbol.iterator]()
ã¡ãœãããæã¡ãŸãããä»ã«ã values()
ãšããIteratorãè¿ãã¡ãœãããæã£ãŠããŸãã
ã¡ãªã¿ã« arr[Symbol.iterator] === arr.values
ã§ãã
å®è£ äŸ
Iteratorãäœãã¯æ¬¡é
ã«è²ãã€ã€ããããè¿ã [Symbol.iterator]()
ã¡ãœãããæã€ãªããžã§ã¯ãïŒã®ã¯ã©ã¹ïŒã§ãã
class MyIterable { [Symbol.iterator] () { return new MyIterator(); } }
å埩å (Iterator)
next()
ã¡ãœãããæã¡ãããã䜿ã£ãŠå埩ã§ãããã®ã
Object.values()
ãšããfor-of
ã for
ã«å解ãããšãã«åºãŠãããã€ã
Property Value Requirements next
A function that returns an IteratorResult object. The returned object must conform to the IteratorResult interface. If a previous call to the next
method of an Iterator has returned an IteratorResult object whosedone
property istrue
, then all subsequent calls to thenext
method of that object should also return an IteratorResult object whosedone
property istrue
. However, this requirement is not enforced.Note 1
Arguments may be passed to the next function but their interpretation and validity is dependent upon the target Iterator. The for-of statement and other common users of Iterators do not pass any arguments, so Iterator objects that expect to be used in such a manner must be prepared to deal with being called with no arguments.
ãããã㣠| å€ | èŠæ± |
---|---|---|
next |
IteratorResult ãªããžã§ã¯ããè¿ãé¢æ°ã | è¿åŽããããªããžã§ã¯ã㯠IteratorResult ã€ã³ã¿ãŒãã§ã€ã¹ã«æºæ ããªããã°ãªããªãããã Iterator ã®ååã® next ã¡ãœããåŒã³åºããè¿ãã IteratorResult ã® done ããããã£ã true ã§ããå Žåã以éã® next ã¡ãœããåŒã³åºããè¿ã IteratorResult ãªããžã§ã¯ãã done ããããã£ã true ã«ãªãã ãã (should) ããã ãããã®èŠæ±ã¯åŒ·å¶ãããªãã |
ããŒã1
åŒæ°ã next é¢æ°ãžäžããŠãè¯ããããããã®è§£éã劥åœæ§ã¯å¯Ÿè±¡ Iterator ã«äŸãã for-of æ§æããã®ä»ã®äžè¬ç㪠Iterator ã®å©çšè ã¯åŒæ°ãäœãäžããªãããããã®ãããªäœæ³ã§ã®å©çšãæ³å®ããã Iterator ãªããžã§ã¯ãã¯ãåŒæ°ãªãã§åŒã°ããå Žåã察åŠããããã«ãªã£ãŠããªããã°ãªããªãã
å®è£ äŸ
å å ããå€ãåºå®ã ãã©ã
class MyIterator { constructor () { this.index = 0; this.values = [11, 22, 33]; } next () { const value = this.values[this.index]; this.index += 1; const result = { done: !value, value }; return result; } }
ä»»æã®ããããã£
next()
ã¯å¿
é ã ãã©ãä»ã« return()
ãš throw()
ãå®è£
ããŠãè¯ãããã§ãã
Property Value Requirements return
A function that returns an IteratorResult object. The returned object must conform to the IteratorResult interface. Invoking this method notifies the Iterator object that the caller does not intend to make any more next
method calls to the Iterator. The returned IteratorResult object will typically have adone
property whose value istrue
, and avalue
property with the value passed as the argument of thereturn
method. However, this requirement is not enforced.throw
A function that returns an IteratorResult object. The returned object must conform to the IteratorResult interface. Invoking this method notifies the Iterator object that the caller has detected an error condition. The argument may be used to identify the error condition and typically will be an exception object. A typical response is to throw
the value passed as the argument. If the method does notthrow
, the returned IteratorResult object will typically have adone
property whose value istrue
.Note 2
Typically callers of these methods should check for their existence before invoking them. Certain ECMAScript language features including
for-of
,yield*
, and array destructuring call these methods after performing an existence check. Most ECMAScript library functions that accept Iterable objects as arguments also conditionally call them.
ãããã㣠| å€ | èŠæ± |
---|---|---|
return |
IteratorResult ãªããžã§ã¯ããè¿ãé¢æ°ã | è¿åŽããããªããžã§ã¯ã㯠IteratorResult ã€ã³ã¿ãŒãã§ã€ã¹ã«æºæ ããªããã°ãªããªãããã®ã¡ãœããã®åŒã³åºã㯠Iterator ãªããžã§ã¯ããžãåŒã³åºãåŽãããä»¥äž next ã¡ãœããåŒã³åºããè¡ãæå³ããªãããšãéç¥ãããè¿åŽããã IteratorResult ã® done ããããã£ã¯ãäžè¬ã« true ã«ãªãã value ããããã£ã¯ return ã¡ãœããã®åŒæ°ã«äžããããå€ãšãªãããã ãããã®èŠæ±ã¯åŒ·å¶ãããªãã |
throw |
IteratorResult ãªããžã§ã¯ããè¿ãé¢æ°ã | è¿åŽããããªããžã§ã¯ã㯠IteratorResult ã€ã³ã¿ãŒãã§ã€ã¹ã«æºæ ããªããã°ãªããªãããã®ã¡ãœããã®åŒã³åºã㯠Iterator ãªããžã§ã¯ããžãåŒã³åºãè
ããšã©ãŒç¶æ
ãæ€åºããããšãéç¥ãããåŒæ°ã¯ãšã©ãŒç¶æ
ç¹å®ã®ããã«äœ¿ã£ãŠãããããŸãå€ãã®å Žåã¯äŸå€ãªããžã§ã¯ãã«ãªãã代衚çãªç®çã¯åŒæ°ãšããŠæž¡ãããå€ã throw ããããšã§ããããã®ã¡ãœããã throw ããªãå Žåãè¿åŽããã IteratorResult ã® done ããããã£ã¯ãäžè¬ã« true ã«ãªãã |
ããŒã2
äžè¬çã«ãããã®ã¡ãœããã®åŒã³åºãåŽã¯ããã®ååšã確èªããŠããåŒã³åºãããšã«ãªãã ãã (should) ã for-of
ã yield*
ãé
åã®å解 (destructuring) ãšãã£ããä¿¡é Œã§ããECMAScriptèšèªã®æ©èœã¯ååšç¢ºèªãå®è¡ããåŸã«ãããã®ã¡ãœãããåŒã³åºããŠããã Iterable ãªããžã§ã¯ããåãä»ããã»ãšãã©ã®ECMAScriptã©ã€ãã©ãªãŒé¢æ°ããŸããæ¡ä»¶æ¬¡ç¬¬ã§ããããåŒã¶ããã«ãªã£ãŠããã
å埩å¯èœãªå埩å
ECMAScriptã§IteratorãšããŠèšè¿°ãããŠãããã®ã¯ããããã %IteratorPrototype%
ãšããç§å¯ã®ãããã¿ã€ããç¶æ¿ããããã«ãªã£ãŠããŸãã
ãã®ãããã¿ã€ãã¯åã« this
ãè¿ãã ãã® [Symbol.iterator]()
ãæã€ãšãããŸãã
ã€ãŸãæšæºã®Iteratorã¯å埩å¯èœã§ãããIteratorãäœãIteratorã¯èªèº«ã§ãã (it === it[Symbol.iterator]()
) ãšããããã§ããã
ãšãããããã§é
åã¯ãã¡ããã®ããšãé
åããæ瀺çã«çæããIteratorããŸã for-of
ã§äœ¿ããã®ã§ãã
const arr = [11, 22, 33]; for (const value of arr) { console.log('arr', value); } // arr 11 // arr 22 // arr 33 const it = arr.values(); for (const value of it) { console.log('it', value); } // it 11 // it 22 // it 33
éåæã®å埩å¯èœãå埩å
for-await-of
ã§äœ¿ãããã€ã
åºæ¬çã«åæã®ãã®ãšåãã£ãœãã
éãã®ã¯ã next()
ãè¿ããã®ãã IteratorResult ãªããžã§ã¯ããããã IteratorResult ãªããžã§ã¯ãã®ãããã¹ãã«ãªã£ãŠãç¹ã
å埩çµæ (IteratorResult)
ããããæžããŠãããã©ãæã£ãŠãã®ã¯å€ã ããªãã§ãå®éãããªã«ãããããã¯ãªããã
Property Value Requirements done
Either true
orfalse
.This is the result status of an iterator next
method call. If the end of the iterator was reacheddone
istrue
. If the end was not reacheddone
isfalse
and a value is available. If adone
property (either own or inherited) does not exist, it is consider to have the valuefalse
.value
Any ECMAScript language value. If done is false
, this is the current iteration element value. If done istrue
, this is the return value of the iterator, if it supplied one. If the iterator does not have a return value,value
isundefined
. In that case, thevalue
property may be absent from the conforming object if it does not inherit an explicitvalue
property.
ãããã㣠| å€ | èŠæ± |
---|---|---|
done |
true ã false ã |
ãã㯠iterator ã® next ã¡ãœããåŒã³åºãã®çµæç¶æ
ã§ãããiteratorãæåŸãŸã§å°éããŠããã° done 㯠true ã«ãªããiteratorãæåŸãŸã§å°éããŠããªããã° done 㯠false ã«ãªãã value ã¯æå¹ã«ãªãã done ããããã£ïŒèªèº«ã®ãã®ã§ãç¶æ¿ãããã®ã§ãïŒãååšããªãå Žå㯠false å€ãæã€ãã®ãšã¿ãªãã |
value |
ECMAScriptèšèªã®ä»»æã®å€ã | done ã false ã®å Žåãããã¯çŸåšã®å埩èŠçŽ ã®å€ã§ããã done ã true ã®å Žåããã㯠iterator ã®æ»ãå€ã§ãããïŒããã°ãïŒ iterator ãæ»ãå€ãæããªãå Žåã value 㯠undefined ã«ãªãããã®å Žåã確èªäžã®ãªããžã§ã¯ããæ確㪠value ããããã£ãç¶æ¿ããŠããªããã° value ããããã£ã¯ãã®ãªããžã§ã¯ãããæ¬ èœããŠããã (may) ã |
ãžã§ãã¬ãŒã¿ãŒ
å埩åã§ãããªããå埩å¯èœã§ãããã®
A Generator object is an instance of a generator function and conforms to both the Iterator and Iterable interfaces.
Generator instances directly inherit properties from the object that is the value of the
prototype
property of the Generator function that created the instance. Generator instances indirectly inherit properties from the Generator Prototype intrinsic, %GeneratorPrototype%.
Generatorãªããžã§ã¯ãã¯generatoré¢æ°ã®ã€ã³ã¹ã¿ã³ã¹ã§ããã Iterator ãš Iterable ã€ã³ã¿ãŒãã§ã€ã¹ã®äž¡æ¹ã«æºæ ãããã®ã§ããã
Generatorã€ã³ã¹ã¿ã³ã¹ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ãçæããGeneratoré¢æ°ã® prototype
ããããã£ã®å€ã§ãããªããžã§ã¯ãããçŽæ¥çã«ããããã£ãç¶æ¿ãããGeneratorã€ã³ã¹ã¿ã³ã¹ã¯åºæã®Generatorãããã¿ã€ãã%GeneratorPrototype%ããéçŽæ¥çã«ããããã£ãç¶æ¿ããã
Generatoré¢æ° (function*(){}
) ã®æ£äœãããããŸãããïŒ
function* f () { yield 1; } f.prototype.sayHello = () => console.log('Hello!'); const it = f(); it.sayHello(); // Hello!
for-of
ãšIterable
GetIterator()
ãšããå
éšåŠçããã£ãŠãããã€ã§ of
å³åŽã®ãªããžã§ã¯ãããäŸã® [Symbol.iterator]()
ãéããŠIteratorãååŸããŠãŸããååŸã§ããªããã° TypeError
ã
第3åŒæ°ã«ä»»æã® method
ãæž¡ããããã«ãªã£ãŠããã©ãä»æ§æžèŠãæãå
šéš @@iterator
ã @@asyncIterator
ã¿ããã
ãã®ä»
Object.values()
vs arr.values()
Object.values(obj)
ã¯ãã ã®é
åãè¿ããŠããã®äžèº«ã obj
ã®ããããã£å€ã«ãªããŸãã
arr.values()
㯠arr
ã®é
ç®ãé ã«è¿ãIteratorãè¿ããŸãã
ããŸã: è±åèª iteration vs repetition
å埩ãšç¹°ãè¿ããã©ã¡ããåããããªæå³ã ãã©ãã©ãéããã ãããã
ããã®åçããããããããïŒåã£ãŠãã®ãã©ããã¯å€æããããããïŒ
Iteration uses an iterator to count through a list of (usually different) items:
Today, I must:
1: go shopping
2: clean the house
3: mow the lawnRepetition does the same thing again, and again, etc…:
One sheep, two sheep, three sheep, …
挫ç»ã®åè¡æ¬ãç¶ããŠèªãã®ã iterate ã§ãåãæ¬ãäœåºŠãèªãã®ã repeat ãŠãªæãã¿ããã
ãããŸã
ã»ãšãã©ãã ã®ç¿»èš³ã«ãªã£ãŠããŸã£ãã
ãŸãä»æ§æžãäžçªããããããããä»æ¹ãªãã
é¢é£
- for-ofã§é åãæ®éã®ãªããžã§ã¯ããå埩ããããïŒé åãšãããããAdvent Calendar2018 â 15æ¥ç®ïŒ
- éåæã«ç¹°ãè¿ããªãfor-await-ofæ§æã䜿ããããã©äœ¿ããªãæ¹ãè¯ããããïŒé åãšãããããAdvent Calendar2018 â 16æ¥ç®ïŒ
åè
- å埩åŠçãããã³ã« | MDN
- ECMAScript® 2018 Language Specification
- 25.1.1 Common Iteration Interfaces
- 25.1.1.1 The Iterable Interface
- 25.1.1.2 The Iterator Interface
- 25.1.2 The %IteratorPrototype% Object
- 25.1.1.5 The IteratorResult Interface
- 25.4 Generator Objects
- 7.4.1 GetIterator ( obj [ , hint [ , method ] ] )
- 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation ( TDZnames, expr, iterationKind )
- differences – Iteration vs. Repetition – English Language & Usage Stack Exchange
- iterate – Dictionary Definition : Vocabulary.com
- repeat – Dictionary Definition : Vocabulary.com