ES6 Iterator 와 for... of 순환
스 트 리밍 기 (Iterator) 는 다양한 데이터 구조 에 통 일 된 접근 체 제 를 제공 하 는 인터페이스 이다.모든 데이터 구 조 는 Iterator 인 터 페 이 스 를 배치 하면 옮 겨 다 니 기 작업 을 완성 할 수 있 습 니 다 (즉, 이 데이터 구 조 를 순서대로 처리 하 는 모든 구성원).
Iterator 의 역할 은 세 가지 가 있 습 니 다.
Iterator 의 옮 겨 다 니 는 과정 은 다음 과 같 습 니 다.
매번 next 방법 을 호출 할 때마다 데이터 구조의 현재 구성원 의 정 보 를 되 돌려 줍 니 다.구체 적 으로 말 하면 value 와 done 두 속성 을 포함 하 는 대상 을 되 돌려 주 는 것 이다.그 중에서 value 속성 은 현재 구성원 의 값 입 니 다. done 속성 은 불 값 입 니 다. 옮 겨 다 니 는 것 이 끝 났 는 지 여 부 를 표시 합 니 다.
다음은 next 방법 을 모 의 하여 값 을 되 돌려 주 는 예 입 니 다.
var it = makeIterator(['a', 'b']);
it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }
function makeIterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{value: undefined, done: true};
}
};
}
위 코드 는 MakeIterator 함 수 를 정의 합 니 다. 이것 은 스 트 리밍 기 생 성 함수 입 니 다. 스 트 리밍 기 대상 을 되 돌려 주 는 역할 을 합 니 다.배열 [a ',' b '] 에서 이 함 수 를 실행 하면 이 배열 의 스 트 리밍 대상 (즉 포인터 대상) it 로 돌아 갑 니 다.
Iterator 는 인터페이스 규격 을 데이터 구조 에 만 추가 하기 때문에 스 트 리밍 기 는 그 데이터 구조 와 실제 적 으로 분 리 된 것 으로 데이터 구조 에 대응 하지 않 는 스 트 리밍 기 대상 을 작성 하거나 스 트 리밍 기 대상 으로 데이터 구 조 를 모 의 할 수 있 습 니 다.다음은 무한 실행 중인 달력 대상 의 예 입 니 다.
var it = idMaker();
it.next().value // '0'
it.next().value // '1'
it.next().value // '2'
// ...
function idMaker() {
var index = 0;
return {
next: function() {
return {value: index++, done: false};
}
};
}
위의 예 에서 스 트 리밍 기 생 성 함수 idMaker 는 스 트 리밍 대상 (즉 포인터 대상) 을 되 돌려 줍 니 다.그러나 대응 하 는 데이터 구조 가 없 거나 옮 겨 다 니 는 대상 이 스스로 데이터 구 조 를 묘사 했다.
TypeScript 의 쓰기 방법 을 사용 하면 스 트 리밍 인터페이스 (Iterable), 포인터 대상 (Iterator) 과 next 방법 으로 값 을 되 돌려 주 는 규격 은 다음 과 같 습 니 다.
interface Iterable {
[Symbol.iterator]() : Iterator,
}
interface Iterator {
next(value?: any) : IterationResult,
}
interface IterationResult {
value: any,
done: boolean,
}
기본 Iterator 인터페이스
for... of 순환 을 사용 하여 특정한 데이터 구 조 를 옮 겨 다 닐 때 이 순환 은 자동 으로 Iterator 인 터 페 이 스 를 찾 습 니 다.하나의 데이터 구조 가 Iterator 인 터 페 이 스 를 배치 하면 우 리 는 이러한 데이터 구 조 를 '옮 겨 다 닐 수 있 는' (iterable) 이 라 고 부른다.
ES6 에 서 는 기본 Iterator 인터페이스 가 데이터 구조의 Symbol. iterator 속성 에 배치 되 어 있 거나, 하나의 데이터 구 조 는 Symbol. iterator 속성 만 있 으 면 '옮 겨 다 닐 수 있 는' 것 으로 볼 수 있 습 니 다. Symbol. iterator 속성 자 체 는 하나의 함수 이 며, 현재 데이터 구조 에서 기본 적 인 스 트 리밍 기 생 성 함수 입 니 다. 이 함 수 를 실행 하면 스 트 리밍 기 를 되 돌려 줍 니 다.
const obj = {
[Symbol.iterator] : function () {
return {
next: function () {
return {
value: 1,
done: true
};
}
};
}
};
위 코드 에서 대상 obj 는 옮 겨 다 닐 수 있 는 (iterable) 입 니 다. Symbol. iterator 속성 이 있 기 때 문 입 니 다. 이 속성 을 실행 하면 옮 겨 다 니 는 대상 을 되 돌려 줍 니 다. 이 대상 의 근본 적 인 특징 은 next 방법 입 니 다. next 방법 을 호출 할 때마다 현재 구성원 을 대표 하 는 정보 대상 을 되 돌려 줍 니 다. value 와 done 두 속성 이 있 습 니 다.
ES6 의 일부 데이터 구 조 는 원래 Iterator 인터페이스 (예 를 들 어 배열) 를 갖 추고 있 습 니 다. 즉, 어떠한 처리 도 하지 않 아 도 for.. of 순환 으로 옮 겨 다 닐 수 있 습 니 다. 이 데이터 구 조 는 원래 Symbol. iterator 속성 을 배 치 했 기 때 문 입 니 다. 다른 데이터 구 조 는 (예 를 들 어 대상) 이 없 기 때 문 입 니 다.. Symbol. iterator 속성 이 배 치 된 데이터 구 조 를 옮 겨 다 니 는 인터페이스 라 고 합 니 다. 이 인 터 페 이 스 를 호출 하면 옮 겨 다 니 는 대상 을 되 돌려 줍 니 다.
원생 Iterator 인 터 페 이 스 를 갖 춘 데이터 구 조 는 다음 과 같다.
let arr = ['a', 'b', 'c'];
let iter = arr[Symbol.iterator]();
iter.next() // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: 'c', done: false }
iter.next() // { value: undefined, done: true }
위의 코드 에서 변수 arr 는 하나의 배열 입 니 다. 원생 은 스 트 리밍 인터페이스 가 있 고 arr 의 Symbol. iterator 속성 에 배치 되 어 있 습 니 다. 따라서 이 속성 을 호출 하면 스 트 리밍 대상 을 얻 을 수 있 습 니 다.
대상 이 for... of 순환 호출 가능 한 Iterator 인 터 페 이 스 를 갖 추 려 면 Symbol. iterator 의 속성 에 스 트 리밍 기 생 성 방법 을 배치 해 야 합 니 다.
class RangeIterator {
constructor(start, stop) {
this.value = start;
this.stop = stop;
}
[Symbol.iterator]() { return this; }
next() {
var value = this.value;
if (value < this.stop) {
this.value++;
return {done: false, value: value};
}
return {done: true, value: undefined};
}
}
function range(start, stop) {
return new RangeIterator(start, stop);
}
for (var value of range(0, 3)) {
console.log(value); // 0, 1, 2
}
위 코드 는 Iterator 인 터 페 이 스 를 배치 하 는 쓰기 입 니 다. Symbol. iterator 속성 은 함수 에 대응 합 니 다. 실행 후 현재 대상 의 스 트 리밍 대상 으로 돌아 갑 니 다.
유사 한 배열 의 대상 (수치 키 이름과 length 속성 이 존재 함) 에 대해 Iterator 인 터 페 이 스 를 배치 하 는 간단 한 방법 은 Symbol. iterator 방법 으로 배열 의 Iterator 인 터 페 이 스 를 직접 참조 하 는 것 입 니 다.
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
//
NodeList.prototype[Symbol.iterator] = [][Symbol.iterator];
[...document.querySelectorAll('div')] //
NodeList 대상 은 배열 과 유사 한 대상 입 니 다. 원래 인 터 페 이 스 를 옮 겨 다 니 며 직접 옮 겨 다 닐 수 있 습 니 다. 위의 코드 에 서 는 인 터 페 이 스 를 배열 의 Symbol. iterator 속성 으로 바 꾸 었 습 니 다. 아무런 영향 이 없 음 을 볼 수 있 습 니 다.
다음은 다른 배열 과 유사 한 대상 이 배열 의 Symbol. iterator 방법 을 호출 하 는 예 입 니 다.
let iterable = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
console.log(item); // 'a', 'b', 'c'
}
일반 대상 에 배열 을 배치 하 는 Symbol. iterator 방법 은 효과 가 없습니다.
let iterable = {
a: 'a',
b: 'b',
c: 'c',
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
console.log(item); // undefined, undefined, undefined
}
Symbol. iterator 방법 이 스 트 리밍 기 생 성 함수 (즉, 스 트 리밍 대상 을 되 돌려 줍 니 다) 가 아니라면 엔진 설명 이 잘못 되 었 습 니 다.
var obj = {};
obj[Symbol.iterator] = () => 1;
[...obj] // TypeError: [] is not a function
Iterator 인터페이스 호출 장소
1. 할당 해제
배열 과 Set 구 조 를 재 구성 할 때 Symbol. iterator 방법 을 기본적으로 호출 합 니 다.
let set = new Set().add('a').add('b').add('c');
let [x,y] = set;
// x='a'; y='b'
let [first, ...rest] = set;
// first='a'; rest=['b','c'];
2. 확장 연산 자
확장 연산 자 (...) 도 기본 Iterator 인 터 페 이 스 를 호출 합 니 다.
//
var str = 'hello';
[...str] // ['h','e','l','l','o']
//
let arr = ['b', 'c'];
['a', ...arr, 'd']
// ['a', 'b', 'c', 'd']
실제로 이 는 하나의 데이터 구조 가 Iterator 인 터 페 이 스 를 배치 하면 확장 연산 자 를 사용 하여 배열 로 전환 할 수 있 는 간편 한 메커니즘 을 제공 했다.
3. yield*
yield * 뒤에 있 는 것 은 옮 겨 다 닐 수 있 는 구조 입 니 다. 이 구조의 옮 겨 다 니 기 인 터 페 이 스 를 호출 합 니 다.
let generator = function* () {
yield 1;
yield* [2,3,4];
yield 5;
};
var iterator = generator();
iterator.next() // { value: 1, done: false }
iterator.next() // { value: 2, done: false }
iterator.next() // { value: 3, done: false }
iterator.next() // { value: 4, done: false }
iterator.next() // { value: 5, done: false }
iterator.next() // { value: undefined, done: true }
4. 다른 장소
배열 의 스 트 리밍 은 스 트 리밍 인 터 페 이 스 를 호출 하기 때문에 배열 을 매개 변수 로 받 아들 이 는 모든 경우 스 트 리밍 인 터 페 이 스 를 호출 합 니 다. 다음은 예 입 니 다.
문자열 의 Iterator 인터페이스
문자열 은 배열 과 유사 한 대상 이 며, 원생 Iterator 인터페이스 가 있 습 니 다.
var someString = "hi";
typeof someString[Symbol.iterator]
// "function"
var iterator = someString[Symbol.iterator]();
iterator.next() // { value: "h", done: false }
iterator.next() // { value: "i", done: false }
iterator.next() // { value: undefined, done: true }
Iterator 인터페이스 와 Generator 함수
Symbol. iterator 방법의 가장 간단 한 실현:
var myIterable = {};
myIterable[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
[...myIterable] // [1, 2, 3]
//
let obj = {
* [Symbol.iterator]() {
yield 'hello';
yield 'world';
}
};
for (let x of obj) {
console.log(x);
}
// hello
// world
옮 겨 다 니 는 대상 의 return (), throw ()
스 트 리밍 대상 은 next 방법 외 에 return 방법 과 throw 방법 도 있 습 니 다. 스 트 리밍 대상 생 성 함 수 를 직접 쓰 면 next 방법 은 반드시 배치 해 야 합 니 다. return 방법 과 throw 방법 은 배치 여 부 를 선택 할 수 있 습 니 다.
return 방법의 사용 장 소 는 for... of 순환 이 앞 당 겨 종료 되면 (오류 가 발생 하거나 break 문 이나 continue 문 이 있 기 때 문) return 방법 을 사용 합 니 다. 대상 이 옮 겨 다 니 기 전에 자원 을 정리 하거나 방출 해 야 한다 면 return 방법 을 배치 할 수 있 습 니 다.
function readLinesSync(file) {
return {
next() {
return { done: false };
},
return() {
file.close();
return { done: true };
},
};
}
위의 코드 에서 함수 readLinesSync 는 파일 대상 을 매개 변수 로 받 아들 여 스 트 리밍 대상 을 되 돌려 줍 니 다. 그 중에서 next 방법 을 제외 하고 return 방법 도 배 치 했 습 니 다. 아래 세 가지 경우 모두 return 방법 을 실행 합 니 다.
//
for (let line of readLinesSync(fileName)) {
console.log(line);
break;
}
//
for (let line of readLinesSync(fileName)) {
console.log(line);
continue;
}
//
for (let line of readLinesSync(fileName)) {
console.log(line);
throw new Error();
}
위의 코드 에 서 는 상황 이 출력 파일 의 첫 줄 이후 return 방법 을 실행 하여 이 파일 을 닫 습 니 다. 상황 2 출력 모든 줄 이후 return 방법 을 실행 하여 이 파일 을 닫 습 니 다. 상황 3 은 return 방법 을 실행 하여 파일 을 닫 은 후에 오 류 를 던 집 니 다.
return 방법 은 대상 을 되 돌려 야 합 니 다. 이것 은 Generator 규격 에 의 해 결 정 된 것 입 니 다.
throw 방법 은 주로 Generator 함수 에 맞 춰 사용 되 며, 일반적인 스 트 리밍 대상 은 이 방법 을 사용 하지 않 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JavaScript로 카드 놀이를 넘기는 애니메이션을 만들려고했습니다.카드를 넘기는 애니메이션을 만들어 보았습니다. 폴더 구성은 다음과 같습니다. 코드는 다음과 같습니다. card_turning.html 다음은 JavaScript 코드입니다. cardTurning.js 결과는, 이런 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.