JavaScript 의 Iterator 와 for - of 순환 을 깊이 해석 합 니 다.

어떻게 배열 의 요 소 를 옮 겨 다 닙 니까?20 년 전, 자 바스 크 립 트 가 나 타 났 을 때, 당신 은 이렇게 할 수 있 습 니 다:
for(varindex = 0; index < myArray.length; index++) {
 console.log(myArray[index]);
}

ES5 부터 내 장 된 foreach 방법 을 사용 할 수 있 습 니 다.
myArray.forEach(function(value) {
 console.log(value);
});

코드 가 더욱 간단 하지만 작은 단점 이 있 습 니 다. break 문 구 를 사용 하여 순환 을 뛰 어 넘 을 수 없고 return 문 구 를 사용 하여 폐쇄 함수 에서 되 돌 릴 수 없습니다.
for - 이런 문법 으로 배열 을 옮 겨 다 니 면 훨씬 편리 할 것 이다.
그럼 for - in 을 사용 하 는 게 어때요?
for(varindex inmyArray) { //           
 console.log(myArray[index]);
}

이러 면 안 돼 요. 왜냐하면:
위 코드 의 index 변 수 는 수치 형식 이 아 닌 '0', '1', '3' 등 문자열 이 될 것 입 니 다.문자열 의 index 를 사용 하여 일부 연산 ("2" + 1 = = "21") 에 참여 하면 연산 결과 가 예상 에 부합 되 지 않 을 수 있 습 니 다.배열 자체 의 요소 가 옮 겨 다 닐 뿐만 아니 라 사용자 가 추가 한 추가 (expando) 요소 도 옮 겨 다 닐 것 입 니 다. 예 를 들 어 특정한 배열 에 이러한 속성 my Array. name 이 있 으 면 특정한 순환 에서 index = "name" 이 나타 날 것 입 니 다.그리고 심지어 배열 원형 체인 의 속성 도 옮 겨 다 닐 수 있다. 가장 신기 한 것 은 어떤 경우 에는 위의 코드 가 임의의 순서 로 배열 요 소 를 옮 겨 다 니 는 것 이다.쉽게 말 하면 for - in 디자인 의 목적 은 키 값 이 맞 는 대상 을 옮 겨 다 니 는 것 입 니 다. 배열 에 그다지 우호 적 이지 않 습 니 다.강력 한 for - of 순환 은 지난번 에 제 가 말씀 드 렸 듯 이 ES6 는 기 존의 JS 코드 의 정상 적 인 운행 에 영향 을 주지 않 습 니 다. 이미 수천 개의 웹 응용 프로그램 이 for - in 의 특성 에 의존 하고 심지어 for - in 이 배열 에 사용 하 는 특성 에 의존 하기 때문에 기 존의 for - in 문법 을 개선 하여 상기 문 제 를 복원 하 는 것 을 제기 한 적 이 없습니다.ES6 가 이 문 제 를 해결 하 는 유일한 방법 은 새로운 순환 문법 을 도입 하 는 것 이다.
이것 이 바로 새로운 문법 이다.
for(var value of myArray) {
 console.log(value);
}

위의 for - in 문법 을 소개 함으로써 이 문법 은 그다지 인상적 이지 않 아 보인다.뒤에 우 리 는 for - of 의 기묘 한 점 을 상세 하 게 소개 할 것 이다. 지금 너 는 알 아야 한다.
    이것 은 배열 을 옮 겨 다 니 는 가장 간단 하고 직접적인 방법 이다.
    모든 for - in 문법 에 존재 하 는 구 덩이 를 피 했 습 니 다.
    foreach () 와 달리 break, continue, return 문 구 를 지원 합 니 다.
for - in 대상 을 옮 겨 다 니 는 속성 입 니 다.
for - of 는 배열 의 요소 처럼 데 이 터 를 옮 겨 다 니 는 데 사 용 됩 니 다.
그러나 이 는 포 오 프 의 모든 특성 이 아니 라 더 멋 진 부분 이 있다.
for - of 를 지원 하 는 기타 집합
for - of 는 배열 만 을 위 한 것 이 아니 라 클래스 배열 의 대상, 예 를 들 어 DOM 대상 의 집합 NodeList 에 도 사용 할 수 있 습 니 다.
문자열 을 옮 겨 다 니 는 데 도 사용 할 수 있 습 니 다. 문자열 을 유 니 코드 문자 의 집합 으로 볼 수 있 습 니 다.
맵 과 set 대상 에 도 적용 된다.
맵 과 Set 대상 은 ES6 의 새로운 대상 이기 때문에 들 어 본 적 이 없 을 지도 모른다. 그 다음 에는 별도의 글 이 있 을 것 이다.만약 네가 다른 언어 에서 이 두 대상 을 사용 한 적 이 있다 면 훨씬 간단 할 것 이다.
예 를 들 어 하나의 set 대상 으로 배열 요 소 를 무 겁 게 할 수 있 습 니 다.
JavaScript
// make a set from an array of words
varuniqueWords = newSet(words);
  
// make a set from an array of words
varuniqueWords = newSet(words);
      Set    ,           ,    :

for(varword of uniqueWords) {
 console.log(word);
}

Map 대상 은 키 쌍 으로 구성 되 어 있 으 며, 옮 겨 다 니 는 방식 이 약간 다 릅 니 다. 두 개의 독립 된 변수 로 각각 키 와 값 을 받 아야 합 니 다.
for(var [key, value] of phoneBookMap) {
 console.log(key + "'s phone number is: " + value);
}

지금까지 JS 는 집합 대상 을 지원 하고 그 다음 에는 더 많은 지원 을 할 것 이라는 것 을 알 고 있 습 니 다.for - of 문법 은 바로 이러한 집합 대상 을 위해 설계 되 었 다.
for - of 는 대상 의 속성 을 직접 옮 겨 다 니 는 데 사용 할 수 없습니다. 대상 의 속성 을 옮 겨 다 니 고 싶다 면 for - in 문 구 를 사용 하거나 아래 방식 을 사용 할 수 있 습 니 다.
// dump an object's own enumerable properties to the console
for(var key of Object.keys(someObject)) {
 console.log(key + ": " + someObject[key]);
}

내부 원리
    "좋 은 예술가 복제, 위대 한 예술가 절도." - 바 브 로 피 카 소
ES6 에 추 가 된 새로운 특성 들 은 규정 이 없 는 것 이 아니 라 대부분 다른 언어 에 사용 되 고 있 으 며, 이러한 특성 이 매우 유용 하 다 는 사실 도 증명 한다.
for - of 문 구 를 보면 C + +, JAVA, C \ # 와 Python 에 유사 한 순환 문 구 를 존재 하고 이 언어 와 표준 라 이브 러 리 의 각종 데이터 구 조 를 옮 겨 다 니 는 데 사용 된다.
다른 언어의 for 와 foreach 문구 와 마찬가지 로 for - of 는 옮 겨 다 니 는 대상 에 게 특정한 방법 을 요구 합 니 다.모든 Array, Map, set 대상 은 하나의 공통점 을 가지 고 있 는데 그것 은 바로 그들 이 하나의 교체 기 (iterator) 방법 을 실현 한 것 이다.
그렇다면 당신 이 원한 다 면 다른 어떤 대상 에 대해 서도 교체 기 방법 을 실현 할 수 있 습 니 다.
이것 은 하나의 대상 을 위해 my Object. toString () 방법 을 실현 하여 JS 엔진 이 대상 을 문자열 로 바 꾸 는 방법 을 알려 주 는 것 과 같 습 니 다.JS 엔진 이 대상 을 어떻게 옮 겨 다 니 는 지 알려 주 는 my Object [Symbol. iterator] () 방법 도 사용 할 수 있 습 니 다.
예 를 들 어 jQuery 를 사용 하고 있 고 each () 방법 을 사용 하 는 것 을 매우 좋아한다 면 지금 은 모든 jQuery 대상 이 for - of 문 구 를 지원 하고 싶 습 니 다. 이렇게 할 수 있 습 니 다.
// Since jQuery objects are array-like,
// give them the same iterator method Arrays have
jQuery.prototype[Symbol.iterator] =
 Array.prototype[Symbol.iterator];

왜 [Symbol. iterator] 문법 이 이렇게 이상해 보 이 는 지 생각 하고 있 을 지도 모른다.이 말 은 도대체 무슨 뜻 입 니까?문 제 는 방법 명 이다. ES 표준 위원 회 는 이 방법 을 iterator () 라 고 명명 할 수 있 지만 기 존 대상 에 'iterator' 라 는 방법 이 이미 존재 할 수 있 기 때문에 코드 혼란 을 초래 하고 최대 호환성 원칙 에 위배 된다.그래서 표준 위원 회 는 문자열 뿐만 아니 라 방법 명 으로 Symbol 을 도입 했다.
Symbol 도 ES6 의 새로운 특성 으로, 뒤에 별도의 글 이 소 개 될 예정 이다.이 제 는 표준 위원회 가 새로운 Symbol 을 도입 한 다 는 것 만 알 아야 한다. 예 를 들 어 Symbol. iterator 는 이전 코드 와 충돌 하지 않 기 위해 서다.유일한 부족 은 문법 이 좀 이상 하 다 는 것 이다. 그러나 이 강력 한 새로운 특성 과 완벽 한 후방 호 환 에 있어 이것 은 보 잘 것 없 는 것 이다.
[Symbol. iterator] () 방법 을 가 진 대상 은 옮 겨 다 닐 수 있 는 것 으로 여 겨 집 니 다 (iterable).뒤의 글 에서 우 리 는 '대상 을 옮 겨 다 닐 수 있다' 는 개념 이 전체 언어 에 관통 되 는 것 을 볼 수 있 습 니 다. for - of 구문 뿐만 아니 라 Map 과 Set 의 구조 함수 와 분석 (Destructuring) 함수, 그리고 새로운 확장 연산 자 에서 도 관련 될 것 입 니 다.
교체 기 개체
일반적으로 우 리 는 처음부터 교체 기 (Iterator) 대상 을 완전히 실현 하지 못 하고 다음 글 은 왜 그런 지 알려 줄 것 이다.그러나 완전 하 게 보기 위해 서 는 교체 기 대상 이 구체 적 으로 어떤 지 살 펴 보 자.(이 절 을 뛰 어 넘 으 면 기술 디 테 일 을 놓 칠 수 있 습 니 다.)
for - of 문 구 를 가 져 오 면 집합 대상 을 옮 겨 다 니 는 [Symbol. iterator] () 방법 을 먼저 호출 합 니 다. 이 방법 은 교체 기 대상 을 되 돌려 줍 니 다. 교체 기 대상 은 'next 방법 을 가 진 모든 대상 일 수 있 습 니 다.그리고 for - of 의 매번 순환 에서 이 교체 기 대상 의 'next 방법' 을 호출 합 니 다.다음은 가장 간단 한 교체 기 대상 입 니 다.
4. 567913. 상기 코드 에서. next () 방법 을 호출 할 때마다 같은 결 과 를 되 돌려 주 었 습 니 다. 이 결 과 는 한편 으로 는 for - of 문장의 순환 이 아직 끝나 지 않 았 음 을 알 리 고 다른 한편 으로 는 for - of 문장의 이번 순환 값 이 0 임 을 알 립 니 다.이것 은 for (value of zeroes Forever Iterator) {} 이 순환 을 의미 합 니 다.물론 전형 적 인 교체 기 는 이렇게 간단 하지 않 을 것 이다.
ES6 의 교체 기 는. done 과. value 라 는 두 가지 속성 을 통 해 매번 의 옮 겨 다 니 는 결 과 를 표시 합 니 다. 이것 이 바로 교체 기의 디자인 원리 입 니 다. 이것 은 다른 언어 에서 의 교체 기와 다 릅 니 다.자바 에 서 는 교체 기 대상 이 각각 'hasNext ()' 와 'next () 두 가지 방법 을 사용 해 야 합 니 다.Python 에서 교체 기 대상 은 하나의. next () 방법 만 있 습 니 다. 옮 겨 다 닐 수 있 는 요소 가 없 을 때 StopIteration 이상 을 던 집 니 다.그러나 근본적으로 이 세 가지 디자인 은 모두 같은 정 보 를 되 돌려 주 었 다.
교체 기 대상 은 return () 과 throw (exc) 두 가지 방법 을 선택적으로 실현 할 수 있다.이상 하거나 break 와 return 연산 자 를 사용 하여 순환 이 일찍 종료 되면 교체 기의. return () 방법 이 호출 됩 니 다. return () 방법 을 통 해 교체 기 대상 이 차지 하 는 자원 을 방출 할 수 있 지만 대부분의 교체 기 는 이 방법 을 실현 할 필요 가 없습니다.throw (exc) 는 또한 하나의 특례 이다. 옮 겨 다 니 는 과정 에서 이 방법 은 영원히 호출 되 지 않 을 것 이다. 이 방법 에 대해 나 는 다음 글 에서 상세 하 게 소개 할 것 이다.
이제 우 리 는 for - of 의 모든 세부 사항 을 알 게 되 었 다. 그러면 우 리 는 간단하게 이 문 구 를 다시 쓸 수 있다.
우선 for - of 순환 체:
var zeroesForeverIterator = {
 [Symbol.iterator]:function() {
 returnthis;
 },
 next:function() {
 return{done: false, value: 0};
 }
};

이것 은 하나의 의미 화 된 실현 일 뿐 일부 바 텀 방법 과 몇 개의 임시 변 수 를 사용 했다.
for(VAR of ITERABLE) {
 STATEMENTS
}

위의 코드 는. return () 방법 을 어떻게 호출 하 는 지 에 관 한 것 이 아니 라 우 리 는 해당 하 는 처 리 를 추가 할 수 있 지만, 나 는 이렇게 하면 우리 가 내부 원리 에 대한 이해 에 영향 을 줄 것 이 라 고 생각한다.for - of 문 구 는 사용 하기 에는 매우 간단 하지만 그 내부 에는 매우 많은 세부 사항 이 있다.
호환성
현재 모든 Firefox 릴 리 스 버 전 은 for - of 문 구 를 지원 합 니 다.Chrome 에서 기본적으로 이 문 구 를 사용 하지 않 습 니 다. 주소 표시 줄 에 입력 할 수 있 습 니 다.chrome://flags 설정 페이지 에 들 어가 서 'Experimental JavaScript' 옵션 을 선택 하 십시오.마이크로소프트 의 Spartan 브 라 우 저 도 이 문 구 를 지원 하지만 IE 는 지원 하지 않 습 니 다.웹 개발 에서 이 문 구 를 사용 하려 면 IE 와 Safari 브 라 우 저 를 호 환 해 야 합 니 다. 바벨 이나 구 글 의 Traceur 같은 컴 파일 러 를 사용 하여 ES6 코드 를 웹 친화 적 인 ES5 코드 로 변환 할 수 있 습 니 다.
서버 쪽 에 대해 서 는 컴 파일 러 가 필요 없습니다. io. js 에서 이 문 구 를 직접 사용 하거나 NodeJS 가 시 작 될 때 -- harmony 시작 옵션 을 사용 할 수 있 습 니 다.
var $iterator = ITERABLE[Symbol.iterator]();
var $result = $iterator.next();
while(!$result.done) {
 VAR = $result.value;
 STATEMENTS
 $result = $iterator.next();
}

본문http://www.jb51.net/article/70106.htm

좋은 웹페이지 즐겨찾기