Skip to content

Latest commit

 

History

History
139 lines (107 loc) · 3.46 KB

22.for of与迭代器.md

File metadata and controls

139 lines (107 loc) · 3.46 KB

for of 与迭代器

Note

迭代器对象: 所谓迭代器,其实就是一个具有 next() 方法的对象,每次调用 next() 都会返回一个结果对象,该结果对象有两个属性,value 表示当前的值,done 表示遍历是否结束。

function createIterator(items) {
    let i = 0;
    return {
        next: function () {
            let done  = i >= items.length;
            let value = !done ? items[i++] : undefined;

            return {
                done: done,
                value: value
            }
        }
    }
}

// iterator 就是一个迭代器对象
var iterator = createIterator([1, 2, 3]);

console.log(iterator.next()); // { done: false, value: 1 }
console.log(iterator.next()); // { done: false, value: 2 }
console.log(iterator.next()); // { done: false, value: 3 }
console.log(iterator.next()); // { done: true, value: undefined }

// ES6 规定,默认的 Iterator 接口部署在数据结构的 Symbol.iterator 属性,或者说,一个数据结构只要具有 Symbol.iterator 属性,就可以认为是"可遍历的"(iterable)。

// v2: 实现一个遍历器对象
const obj = {
    value: 1
};
obj[Symbol.iterator] = function () {
    return createIterator([1, 2, 3])
}
for (let value of obj) {
    console.log(value);
}

// TODO: 默认部署了 Symbol.iterator 属性有哪些呢?
// 1. 数组
// 2. Set
// 3. Map
// 4. 类数组对象,如 arguments 对象、DOM NodeList 对象
// 5. Generator 对象
// 6. 字符串

// TODO; 如何实现一个forof函数呢?
function forOf(obj, cb) {
    let iterable, result;

    if (typeof obj[Symbol.iterator] !== "function")
        throw new TypeError(result + " is not iterable");
    if (typeof cb !== "function") throw new TypeError("cb must be callable");

    // 实际上是一个函数,调用这个函数,返回的是一个对象
    iterable = obj[Symbol.iterator]();

    result = iterable.next();
    while (!result.done) {
        cb(result.value);
        result = iterable.next();
    }
}

// 为了更好的访问对象中的内容,比如有的时候我们仅需要数组中的值,但有的时候不仅需要使用值还需要使用索引,ES6 为数组、Map、Set 集合内建了以下三种迭代器:
//
// 1. entries() 返回一个遍历器对象,用来遍历[键名, 键值]组成的数组。对于数组,键名就是索引值。
// 2. keys() 返回一个遍历器对象,用来遍历所有的键名。
// 3. values() 返回一个遍历器对象,用来遍历所有的键值。
var colors = ["red", "green", "blue"];

for (let index of colors.keys()) {
    console.log(index);
}

// 0
// 1
// 2

for (let color of colors.values()) {
    console.log(color);
}

// red
// green
// blue

for (let item of colors.entries()) {
    console.log(item);
}

// [ 0, "red" ]
// [ 1, "green" ]
// [ 2, "blue" ]


// 遍历 Map 数据结构的时候可以顺便结合解构赋值:
const valuess = new Map([["key1", "value1"], ["key2", "value2"]]);

for (let [key, value] of valuess) {
    console.log(key + ":" + value);
}

// key1:value1
// key2:value2




// Map 类型与数组类似,但是对于 Set 类型需要注意以下:
var colors = new Set(["red", "green", "blue"]);

for (let index of colors.keys()) {
    console.log(index);
}

// red
// green
// blue

for (let color of colors.values()) {
    console.log(color);
}

// red
// green
// blue

for (let item of colors.entries()) {
    console.log(item);
}

// [ "red", "red" ]
// [ "green", "green" ]
// [ "blue", "blue" ]