From da78a9e329e272dedb2400b79a3bdeebff387d47 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:17 -0500 Subject: initial commit --- .../reference/iteration_protocols/index.html | 394 +++++++++++++++++++++ 1 file changed, 394 insertions(+) create mode 100644 files/ko/web/javascript/reference/iteration_protocols/index.html (limited to 'files/ko/web/javascript/reference/iteration_protocols/index.html') diff --git a/files/ko/web/javascript/reference/iteration_protocols/index.html b/files/ko/web/javascript/reference/iteration_protocols/index.html new file mode 100644 index 0000000000..bddc56a50f --- /dev/null +++ b/files/ko/web/javascript/reference/iteration_protocols/index.html @@ -0,0 +1,394 @@ +--- +title: Iteration protocols +slug: Web/JavaScript/Reference/Iteration_protocols +translation_of: Web/JavaScript/Reference/Iteration_protocols +--- +
{{jsSidebar("More")}}
+ +

ECMAScript 2015 (ES6)에는 새로운 문법이나 built-in 뿐만이 아니라, protocols(표현법들)도 추가되었습니다. 이 protocol 은 일정 규칙만 충족한다면 어떠한 객체에 의해서도 구현될 수 있습니다.

+ +

2개의 protocol이 있습니다 : iterable protocol 과 iterator protocol.

+ +

The iterable protocol

+ +

iterable protocol 은 JavaScript 객체들이, 예를 들어 {{jsxref("Statements/for...of", "for..of")}} 구조에서 어떠한 value 들이 loop 되는 것과 같은 iteration 동작을 정의하거나 사용자 정의하는 것을 허용합니다. 다른 type 들({{jsxref("Object")}} 와 같은)이 그렇지 않은 반면에, 어떤 built-in type 들은 {{jsxref("Array")}} 또는 {{jsxref("Map")}} 과 같은 default iteration 동작으로 built-in iterables 입니다.

+ +

iterable 하기 위해서 object는 @@iterator 메소드를 구현해야 합니다. 이것은 object (또는 prototype chain 의 오브젝트 중 하나) 가 {{jsxref("Symbol.iterator")}} key 의 속성을 가져야 한다는 것을 의미합니다 :

+ + + + + + + + + + + + + + +
PropertyValue
[Symbol.iterator]object를 반환하는, arguments 없는 function. iterator protocol 을 따른다.
+ +

어떠한 객체가 반복(Iterate)되어야 한다면 이 객체의 @@iterator 메소드가 인수없이 호출되고, 반환된 iterator는 반복을 통해서 획득할 값들을 얻을 때 사용됩니다.

+ +

The iterator protocol

+ +

iterator protocol 은 value( finite 또는 infinite) 들의 sequence 를 만드는 표준 방법을 정의합니다. 

+ +

객체가 next() 메소드를 가지고 있고, 아래의 규칙에 따라 구현되었다면 그 객체는 iterator이다:

+ + + + + + + + + + + + +
PropertyValue
next +

아래 2개의 속성들을 가진 object 를 반환하는 arguments 없는 함수 :

+ +
    +
  • done (boolean) + +
      +
    • Iterator(반복자)가 마지막 반복 작업을 마쳤을 경우 true. 만약 iterator(반복자)에 return 값이 있다면 value의 값으로 지정된다. 반환 값에 대한 설명은 여기.
    • +
    • Iterator(반복자)의 작업이 남아있을 경우 false. Iterator(반복자)에 done 프로퍼티 자체를 특정짓지 않은 것과 동일하다.
    • +
    +
  • +
  • value - Iterator(반복자)으로부터 반환되는 모든 자바스크립트 값이며 done이 true일 경우 생략될 수 있다.
  • +
+
+ +

몇몇 iterator들은 iterable(반복 가능)이다:

+ +
var someArray = [1, 5, 7];
+var someArrayEntries = someArray.entries();
+
+someArrayEntries.toString();           // "[object Array Iterator]"
+someArrayEntries === someArrayEntries[Symbol.iterator]();    // true
+
+ +

 Iteration protocols 사용 예시

+ +

{{jsxref("String")}} 은 built-in iterable 객체의 한 예시입니다.

+ +
var someString = "hi";
+typeof someString[Symbol.iterator];          // "function"
+
+ +

String 의 기본 iterator 는 string 의 문자를 하나씩 반환합니다.

+ +
var iterator = someString[Symbol.iterator]();
+iterator + "";                               // "[object String Iterator]"
+
+iterator.next();                             // { value: "h", done: false }
+iterator.next();                             // { value: "i", done: false }
+iterator.next();                             // { value: undefined, done: true }
+ +

spread operator와 같은 특정 내장 구조(built-in constructs)들은 실제로는 동일한 iteration protocol을 사용한다:

+ +
[...someString]                              // ["h", "i"]
+ +

사용자만의 @@iterator를 특정함으로써 원하는 반복 행위(iteration behavior)를 설정할 수 있다:

+ +
var someString = new String("hi");          // need to construct a String object explicitly to avoid auto-boxing
+
+someString[Symbol.iterator] = function() {
+  return { // this is the iterator object, returning a single element, the string "bye"
+    next: function() {
+      if (this._first) {
+        this._first = false;
+        return { value: "bye", done: false };
+      } else {
+        return { done: true };
+      }
+    },
+    _first: true
+  };
+};
+
+ +

재설정된 @@iterator가 어떻게 내장 구조(built-in constructs)의 반복 행위에 영향을 주는지 참고:

+ +
[...someString];                              // ["bye"]
+someString + "";                              // "hi"
+
+ +

Iterable 예시

+ +

내장 iterables

+ +

{{jsxref("String")}}, {{jsxref("Array")}}, {{jsxref("TypedArray")}}, {{jsxref("Map")}} and {{jsxref("Set")}} 는 모두 내장 iterable이다. 이 객체들의 프로토타입 객체들은 모두 @@iterator 메소드를 가지고 있기 때문이다.

+ +

사용자 정의된 iterables

+ +

이렇게 고유한 iterables 를 만들 수 있다.

+ +
var myIterable = {};
+myIterable[Symbol.iterator] = function* () {
+    yield 1;
+    yield 2;
+    yield 3;
+};
+[...myIterable]; // [1, 2, 3]
+
+ +

Iterable을 허용하는 내장 API들

+ +

Iterable을 허용하는 많은 내장 API들이 있다. 예를 들어: {{jsxref("Map", "Map([iterable])")}}, {{jsxref("WeakMap", "WeakMap([iterable])")}}, {{jsxref("Set", "Set([iterable])")}} and {{jsxref("WeakSet", "WeakSet([iterable])")}}이 그것이다:

+ +
var myObj = {};
+new Map([[1,"a"],[2,"b"],[3,"c"]]).get(2);               // "b"
+new WeakMap([[{},"a"],[myObj,"b"],[{},"c"]]).get(myObj); // "b"
+new Set([1, 2, 3]).has(3);                               // true
+new Set("123").has("2");                                 // true
+new WeakSet(function*() {
+    yield {};
+    yield myObj;
+    yield {};
+}()).has(myObj);                                         // true
+
+ +

뿐만 아니라 {{jsxref("Promise.all", "Promise.all(iterable)")}}, {{jsxref("Promise.race", "Promise.race(iterable)")}}와 {{jsxref("Array.from", "Array.from()")}} 또한 해당된다.

+ +

Iterable과 함께 사용되는 문법

+ +

for-of loops, spread operator, yield* destructuring assignment는 iterable과 함께 사용되는 구문(statements)과 표현(expressions)이다.

+ +
for(let value of ["a", "b", "c"]){
+    console.log(value);
+}
+// "a"
+// "b"
+// "c"
+
+[..."abc"]; // ["a", "b", "c"]
+
+function* gen(){
+  yield* ["a", "b", "c"];
+}
+
+gen().next(); // { value:"a", done:false }
+
+[a, b, c] = new Set(["a", "b", "c"]);
+a // "a"
+
+
+ +

잘 정의되지 못한 iterables

+ +

만약 Iterable의 @@iterator 메소드가 iterator 객체를 반환하지 않는다면 그것은 잘 정의되지 못한 iterable이라고 할 수 있다. 이러한 iterable을 사용하는 것은 런타임 예외나 예상치 못한 결과를 불러올 수 있다:

+ +
var nonWellFormedIterable = {}
+nonWellFormedIterable[Symbol.iterator] = () => 1
+[...nonWellFormedIterable] // TypeError: [] is not a function
+
+ +

Iterator 예시

+ +

간단한 iterator

+ +
function makeIterator(array){
+    var nextIndex = 0;
+
+    return {
+       next: function(){
+           return nextIndex < array.length ?
+               {value: array[nextIndex++], done: false} :
+               {done: true};
+       }
+    };
+}
+
+var it = makeIterator(['yo', 'ya']);
+
+console.log(it.next().value); // 'yo'
+console.log(it.next().value); // 'ya'
+console.log(it.next().done);  // true
+
+ +

무한 iterator

+ +
function idMaker(){
+    var index = 0;
+
+    return {
+       next: function(){
+           return {value: index++, done: false};
+       }
+    };
+}
+
+var it = idMaker();
+
+console.log(it.next().value); // '0'
+console.log(it.next().value); // '1'
+console.log(it.next().value); // '2'
+// ...
+
+ +

Generator와 함께 사용된 iterator

+ +
function* makeSimpleGenerator(array){
+    var nextIndex = 0;
+
+    while(nextIndex < array.length){
+        yield array[nextIndex++];
+    }
+}
+
+var gen = makeSimpleGenerator(['yo', 'ya']);
+
+console.log(gen.next().value); // 'yo'
+console.log(gen.next().value); // 'ya'
+console.log(gen.next().done);  // true
+
+
+
+function* idMaker(){
+    var index = 0;
+    while(true)
+        yield index++;
+}
+
+var gen = idMaker();
+
+console.log(gen.next().value); // '0'
+console.log(gen.next().value); // '1'
+console.log(gen.next().value); // '2'
+// ...
+
+ +

generator object 는 iterator 또는 iterable 인가?

+ +

generator object 는 iterator 이면서 iterable 입니다.

+ +
var aGeneratorObject = function*(){
+    yield 1;
+    yield 2;
+    yield 3;
+}();
+typeof aGeneratorObject.next;
+// "function", 이것은 next 메서드를 가지고 있기 때문에 iterator입니다.
+typeof aGeneratorObject[Symbol.iterator];
+// "function", 이것은 @@iterator 메서드를 가지고 있기 때문에 iterable입니다.
+aGeneratorObject[Symbol.iterator]() === aGeneratorObject;
+// true, 이 Object의 @@iterator 메서드는 자기자신(iterator)을 리턴하는 것으로 보아 잘 정의된 iterable이라고 할 수 있습니다.
+[...aGeneratorObject];
+// [1, 2, 3]
+
+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(39.0)}}{{CompatGeckoDesktop("27.0")}}{{CompatNo}}26{{CompatNo}}
IteratorResult object instead of throwing{{CompatVersionUnknown}}{{CompatGeckoDesktop("29.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatGeckoMobile("27.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatChrome(39.0)}}
IteratorResult object instead of throwing{{CompatNo}}{{CompatUnknown}}{{CompatGeckoMobile("29.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}
+
+ +

Firefox-specific notes

+ +

IteratorResult object returned instead of throwing

+ +

Starting 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)}}).

+ +

Iterator property and @@iterator symbol

+ +

From Gecko 17 (Firefox 17 / Thunderbird 17 / SeaMonkey 2.14) to Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2) the iterator property was used (bug 907077), and from Gecko 27 to Gecko 35 the "@@iterator" placeholder was used. In Gecko 36 (Firefox 36 / Thunderbird 36 / SeaMonkey 2.33), the @@iterator symbol got implemented (bug 918828).

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-iteration', 'Iteration')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-iteration', 'Iteration')}}{{Spec2('ESDraft')}} 
+ +

See also

+ + -- cgit v1.2.3-54-g00ecf