ES6-Iterator
16624 단어 ES6JavaScript
소개 하 다.
기 존의 집합 을 나타 내 는 데이터 구 조 는 주로 배열 과 대상 이 고 ES6 는 Map 과 Set 을 추 가 했 으 며 Iterator 는 통 일 된 인터페이스 체제 로 서로 다른 데이터 구 조 를 처리 하 는 데 사용 되 었 다.
// Symbol.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 }
역할.
과정 을 편력 하 다
// 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};
}
};
}
원생 Iterator 인터페이스 데이터 구 조 를 갖 춘:
대상 이 for... of 순환 호출 가능 한 Iterator 인 터 페 이 스 를 갖 추 려 면 Symbol. iterator 속성 에 스 트 리밍 기 생 성 방법 을 배치 해 야 합 니 다.
// 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
}
//
// Symbol.iterator , iterator, next , ,
function Obj(value) {
this.value = value;
this.next = null;
}
Obj.prototype[Symbol.iterator] = function() {
var iterator = { next: next };
var current = this;
function next() {
if (current) {
var value = current.value;
current = current.next;
return { done: false, value: value };
} else {
return { done: true };
}
}
return iterator;
}
var one = new Obj(1);
var two = new Obj(2);
var three = new Obj(3);
one.next = two;
two.next = three;
for (var i of one){
console.log(i); // 1, 2, 3
}
// Iterator
let obj = {
data: [ 'hello', 'world' ],
[Symbol.iterator]() {
const self = this;
let index = 0;
return {
next() {
if (index < self.data.length) {
return {
value: self.data[index++],
done: false
};
} else {
return { value: undefined, done: true };
}
}
};
}
};
유사 한 배열 의 대상 (수치 키 이름과 length 속성 이 존재 함) 에 대해 Iterator 인 터 페 이 스 를 배치 하 는 간단 한 방법 은 Symbol. iterator 방법 으로 배열 의 Iterator 인 터 페 이 스 를 직접 참조 하 는 것 입 니 다.
// NodeList , ,
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
//
NodeList.prototype[Symbol.iterator] = [][Symbol.iterator];
[...document.querySelectorAll('div')] //
// 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 인터페이스 호출 장소
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'];
// , , Iterator , 。 , Iterator , ,
//
var str = 'hello';
[...str] // ['h','e','l','l','o']
//
let arr = ['b', 'c'];
['a', ...arr, 'd']
// ['a', 'b', 'c', 'd']
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 }
문자열 의 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 }
// Symbol.iterator ,
var str = new String("hi");
[...str] // ["h", "i"]
str[Symbol.iterator] = function() {
return {
next: function() {
if (this._first) {
this._first = false;
return { value: "bye", done: false };
} else {
return { done: true };
}
},
_first: true
};
};
// str Symbol.iterator , (...) bye, hi
[...str] // ["bye"]
str // "hi"
Iterator 인터페이스 와 Generator 함수
Symbol. iterator 방법의 가장 간단 한 실현 은 Generator 함 수 를 사용 하 는 것 입 니 다.
// Symbol.iterator , yield
let 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 순환 이 미리 종료 되면 return 방법 을 사용 합 니 다.대상 이 옮 겨 다 니 기 전에 자원 을 정리 하거나 방출 해 야 한다 면 return 방법 을 배치 할 수 있 습 니 다.
// readLinesSync , , next , return
function readLinesSync(file) {
return {
[Symbol.iterator]() {
return {
next() {
return { done: false };
},
return() {
file.close();
return { done: true };
}
};
},
};
}
// , return
// , return ,
for (let line of readLinesSync(fileName)) {
console.log(line);
break;
}
// return ,
for (let line of readLinesSync(fileName)) {
console.log(line);
throw new Error();
}
주: return 방법 은 대상 을 되 돌려 야 합 니 다. 이것 은 Generator 규격 이 결정 하 는 throw 방법 입 니 다. 주로 Generator 함수 에 맞 춰 사용 합 니 다. 일반적인 스 트 리밍 대상 은 이 방법 을 사용 하지 않 습 니 다.
for... of circle 순환
var arr = ['a', 'b', 'c', 'd'];
for (let a in arr) {
console.log(a); // 0 1 2 3
}
for (let a of arr) {
console.log(a); // a b c d
}
배열 원생 은 iterator 인터페이스 (즉, Symbol. iterator 속성 을 기본 으로 배치 합 니 다) 를 갖 추고 있 습 니 다. for.. of 순환 은 본질 적 으로 이 인터페이스 에서 발생 하 는 스 트 리밍 기 를 호출 하 는 것 입 니 다.
// obj arr Symbol.iterator , obj for...of , arr
const arr = ['red', 'green', 'blue'];
for(let v of arr) {
console.log(v); // red green blue
}
const obj = {};
obj[Symbol.iterator] = arr[Symbol.iterator].bind(arr);
for(let v of obj) {
console.log(v); // red green blue
}
for... of 순환 은 배열 인 스 턴 스 를 대체 할 수 있 는 foreach 방법 입 니 다.
const arr = ['red', 'green', 'blue'];
arr.forEach(function (element, index) {
console.log(element); // red green blue
console.log(index); // 0 1 2
});
JavaScript 기 존의 for... in 순환, 대상 의 키 만 얻 을 수 있 습 니 다. 키 값 을 직접 가 져 올 수 없습니다.
var arr = ['a', 'b', 'c', 'd'];
for (let a in arr) {
console.log(a); // 0 1 2 3
}
for (let a of arr) {
console.log(a); // a b c d
}
주: for... of 순환 호출 스 트 리밍 인터페이스, 배열 의 스 트 리밍 인 터 페 이 스 는 디지털 색인 이 있 는 속성 만 되 돌려 줍 니 다.
let arr = [3, 5, 7];
arr.foo = 'hello';
for (let i in arr) {
console.log(i); // "0", "1", "2", "foo"
}
for (let i of arr) {
console.log(i); // "3", "5", "7"
}
for... 의 장점:
단점
Set 와 Map 구조
Set 와 Map 구조 도 원생 Iterator 인터페이스 가 있어 for... of 순환 을 직접 사용 할 수 있 습 니 다.
var engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]);
for (var e of engines) {
console.log(e);
}
// Gecko
// Trident
// Webkit
var es6 = new Map();
es6.set("edition", 6);
es6.set("committee", "TC39");
es6.set("standard", "ECMA-262");
for (var [name, value] of es6) {
console.log(name + ": " + value);
}
// edition: 6
// committee: TC39
// standard: ECMA-262
주:
let map = new Map().set('a', 1).set('b', 2);
for (let pair of map) {
console.log(pair);
}
// ['a', 1]
// ['b', 2]
for (let [key, value] of map) {
console.log(key + ' : ' + value);
}
// a : 1
// b : 2
계산 생 성 된 데이터 구조
일부 데이터 구 조 는 기 존의 데이터 구 조 를 바탕 으로 계산 하여 생 성 된 것 이다.예 를 들 어 ES6 의 배열, Set, Map 은 모두 다음 과 같은 세 가지 방법 을 배 치 했 고 호출 한 후에 모두 옮 겨 다 니 는 대상 으로 돌아 갔다.
let arr = ['a', 'b', 'c'];
for (let pair of arr.entries()) {
console.log(pair);
}
// [0, 'a']
// [1, 'b']
// [2, 'c']
배열 과 유사 한 대상
유사 한 배열 의 대상 은 여러 가지 유형 을 포함한다.
//
let str = "hello";
for (let s of str) {
console.log(s); // h e l l o
}
// DOM NodeList
let paras = document.querySelectorAll("p");
for (let p of paras) {
p.classList.add("test");
}
// arguments
function printArgs() {
for (let x of arguments) {
console.log(x);
}
}
printArgs('a', 'b');
// 'a'
// 'b'
문자열 에 있어 for... of 순환 은 32 비트 UTF - 16 문 자 를 정확하게 식별 하 는 특징 이 있 습 니 다.
for (let x of 'a\uD83D\uDC0A') {
console.log(x);
}
// 'a'
// '\uD83D\uDC0A'
모든 유사 한 배열 의 대상 이 Iterator 인 터 페 이 스 를 가지 고 있 는 것 은 아 닙 니 다. 간단 한 해결 방법 은 Array. from 방법 으로 배열 로 바 꾸 는 것 입 니 다.
let arrayLike = { length: 2, 0: 'a', 1: 'b' };
//
for (let x of arrayLike) {
console.log(x);
}
//
for (let x of Array.from(arrayLike)) {
console.log(x);
}
대상
일반적인 대상 에 대해 for... of 구 조 는 직접 사용 할 수 없고 오류 가 발생 할 수 있 습 니 다. Iterator 인 터 페 이 스 를 배치 해 야 사용 할 수 있 습 니 다.하지만, for... in 순환 은 키 이름 을 옮 겨 다 닐 수 있 습 니 다.
let es6 = {
edition: 6,
committee: "TC39",
standard: "ECMA-262"
};
for (let e in es6) {
console.log(e);
}
// edition
// committee
// standard
for (let e of es6) {
console.log(e);
}
// TypeError: es6[Symbol.iterator] is not a function
하나의 해결 방법 은 Object. keys 방법 으로 대상 의 키 이름 을 배열 로 만 든 다음 이 배열 을 옮 겨 다 니 는 것 이다.
for (var key of Object.keys(someObject)) {
console.log(key + ': ' + someObject[key]);
}
또 다른 방법 은 Generator 함 수 를 사용 하여 대상 을 다시 포장 하 는 것 이다.
function* entries(obj) {
for (let key of Object.keys(obj)) {
yield [key, obj[key]];
}
}
for (let [key, value] of entries(obj)) {
console.log(key, '->', value);
}
// a -> 1
// b -> 2
// c -> 3
다른 문법 과 의 비교
배열 의 경우 자바 스 크 립 트 는 여러 가지 문법 을 제공 합 니 다.가장 원시 적 인 문법 은 for 순환 이다
//
for (var index = 0; index < myArray.length; index++) {
console.log(myArray[index]);
}
따라서 배열 은 내 장 된 foreach 방법 을 제공 합 니 다.
// , forEach ,break return
myArray.forEach(function (value) {
console.log(value);
});
for... in 순환 으로 배열 의 키 이름 을 옮 겨 다 닐 수 있 습 니 다.
for (var index in myArray) {
console.log(myArray[index]);
}
for... in 순환 의 몇 가지 단점:
한 마디 로 하면 for... in 순환 은 주로 대상 을 옮 겨 다 니 기 위해 설 계 된 것 으로 배열 에 적용 되 지 않 습 니 다.
for... of 순환 은 위의 몇 가지 방법 에 비해 현저 한 장점 이 있 습 니 다.
for (let value of myArray) {
console.log(value);
}
// break , for...of
// 1000 。 1000, break for...of
for (var n of fibonacci) {
if (n > 1000)
break;
console.log(n);
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Javascript] Tagged Template Strings이전에 이라는 형태로 문자열에 변수를 삽입하는 방법을 배웠었습니다. 오늘 다룰 문법은 템플릿 문자을 발전시킨 Tagged Template Strings(Literals)에 대해서 알아보도록 하겠습니다. Tagged ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.