1.迭代器是帶有特殊接口的對象
,返回一個next
方法,該方法中同時又value
和done
屬性,當再沒有值能夠迭代時,value
爲undefined
,done
爲true
,不然value
爲當前值,done
爲false
javascript
2.根據上面的描述實現一個迭代器,以下:java
let iterator = {
i: 0,
items: [2, 4, 6],
next() {
let value, done;
done = (this.i === this.items.length);
value = done ? undefined : this.items[this.i++];
return {
value: value,
done: done
}
}
};
console.log(iterator.next()); //{value: 2, done: false}
console.log(iterator.next()); //{value: 4, done: false}
console.log(iterator.next()); //{value: 6, done: false}
console.log(iterator.next()); //{value: undefined, done: true}
複製代碼
1.生成器是返回迭代器的函數,以下:數組
function *createIterator() {
yield 1;
yield 2;
yield 3;
}
let iterator = createIterator();
console.log(iterator.next()); //{value: 1, done: false}
console.log(iterator.next()); //{value: 2, done: false}
console.log(iterator.next()); //{value: 3, done: false}
console.log(iterator.next()); //{value: undefined, done: true}
複製代碼
2.生成器有幾點要注意的:函數
1.可迭代類型:指那些包含Symbol.iterator
屬性的對象,該屬性定義了返回迭代器的函數(如:數組,set,map等)ui
2.for-of循環能夠循環可迭代類型,for-of循環會在可迭代類型每次執行後調用next()並將結果存儲在變量中,循環會持續進行,直到結果對象的done屬性爲truethis
3.for-of循環會調用數組的Symbol.iterator
屬性來獲取迭代器(該方法由幕後的js引擎調用),並將調用iterator.next(),並將該結果對象的value屬性的值賦給num,直到done爲true,循環會退出,num不會被賦給undefined,代碼以下:spa
let values = [1, 2, 3];
for (let item of values) {
console.log(item); //1 2 3
}
複製代碼
4.對於非可迭代對象,如null
和undefined
,使用for-of循環會拋出錯誤代理
5.能夠在for-of循環中使用解構code
let map = new Map();
map.set('name', 'sxt');
map.set('age', 2);
for(let [key, value] of map) {
console.log(key + " = " + value);
}
//輸出:
//name = sxt
//age = 2
複製代碼
6.for-of循環能夠用於循環NodeList對象
1.能夠用Symbol.iterator
屬性來訪問對象默認的迭代器,如:
let arr = [6, 7, 8];
let iterator = arr[Symbol.iterator]();
console.log(iterator.next()); //{value: 6, done: false}
console.log(iterator.next()); //{value: 7, done: false}
console.log(iterator.next()); //{value: 8, done: false}
console.log(iterator.next()); //{value: undefined, done: true}
複製代碼
2.判斷一個對象是否能夠迭代,能夠經過判斷Symbol.iterator
屬性是不是一個函數來實現,如:
function isIterator(obj) {
return typeof obj[Symbol.iterator] === 'function';
}
let arr = [1, 3, 4];
let num = 1;
console.log(isIterator(arr)); //true
console.log(isIterator(num)); //false
複製代碼
3.建立可迭代類型: 咱們本身定義的對象默認是不可迭代類型,可是咱們能夠經過設置Symbol.iterator
屬性來使這個對象能夠迭代。由於前面第3點有講到,判斷一個對象是否能夠迭代,實際上是經過Symbol.iterator
屬性來肯定的,由此能夠建立下面的對象
let obj = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
}
};
for (let item of obj) {
console.log(item); //1 2 3
}
複製代碼
1.咱們日常迭代數組,set和map時,能拿到迭代的值,是由於這些集合中有內置的迭代器,如
let arr = [1, 3, 5];
let set = new Set();
set.add('time');
set.add('user');
set.add('family');
let map = new Map();
map.set('name', 'sxt');
map.set('age', 12);
map.set('sister', 'andy');
for(let item of arr) {
console.log(item); // 1 3 5
}
for(let item of set) {
console.log(item); //time user family
}
for(let item of map) {
console.log(item); //["name", "sxt"] ["age", 12] ["sister", "andy"]
}
複製代碼
2.內置迭代器分爲三種
3.數組的entries返回的是[索引,值]
,set的entries是[值,值]
,由於set的鍵值是同樣的,map的entries是[鍵名,鍵值]
,如:
let arr = [1, 3, 5];
let set = new Set();
set.add('time');
set.add('user');
set.add('family');
let map = new Map();
map.set('name', 'sxt');
map.set('age', 12);
map.set('sister', 'andy');
for(let item of arr.entries()) {
console.log(item); // [0, 1] [1, 3] [2, 5]
}
for(let item of set.entries()) {
console.log(item); //["time", "time"] ["user", "user"] ["family", "family"]
}
for(let item of map.entries()) {
console.log(item); //["name", "sxt"] ["age", 12] ["sister", "andy"]
}
複製代碼
4.數組的keys返回的索引,set的keys返回的仍是值,map的keys返回的是值 5.數組,set,map的values返回的都是值
1.咱們能夠向迭代器中傳遞參數
function *createIterator() {
let first = yield 1;
let second = yield first + 2;
yield second + 3;
}
let iterator = createIterator();
console.log(iterator.next()); //{value: 1, done: false}
console.log(iterator.next(4)); //{value: 6, done: false}
console.log(iterator.next(5)); //{value: 8, done: false}
console.log(iterator.next()); //{value: undefined, done: true}
複製代碼
function *createIterator() {
yield 1;
return 133;
yield 2;
yield 3;
}
let iterator = createIterator();
console.log(iterator.next()); //{value: 1, done: false}
console.log(iterator.next(4)); //{value: 133, done: true}
console.log(iterator.next(5)); //{value: undefined, done: true}
console.log(iterator.next()); //{value: undefined, done: true}
複製代碼
1.即,在一個生成器中調用另外的生成器,有時候,這樣的操做會更加的實用
function *create1() {
yield 1;
yield 2;
yield 3;
}
function *create() {
yield *create1();
yield true;
}
let iterator = create();
console.log(iterator.next()); //{value: 1, done: false}
console.log(iterator.next()); //{value: 2, done: false}
console.log(iterator.next()); //{value: 3, done: false}
console.log(iterator.next()); //{value: true, done: false}
console.log(iterator.next()); //{value: undefined, done: true}
複製代碼