SOURCE

// /*
//     Iterator迭代器的实现原理
// */
// function getIterator(list){
//     let index = 0;
//     return {
//         next: function() {
//             let done = index >= list.length;
//             let value = done ? undefined : list[index++]

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

// let it = getIterator(['a', 'b', 'c']);

// console.log(it.next())
// console.log(it.next())
// console.log(it.next())
// console.log(it.next())
// console.log(it.next())




// /*
//     一个不可迭代对象转换成可迭代对象供 for of 消费

// */

// let obj = {}
// for(let i of obj){} // 报错 Uncaught TypeError: obj is not iterable

// var iteratorObj = {
//     items: [100,200,300],
//     [Symbol.iterator]: function(){
//         let self = this;
//         let i = 0;

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

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

// }

// for(let item of iteratorObj) {
//     console.log(item)
// }



// /*
//     获取数组的迭代对象
// */
// var arr = [100,200,300]

// var iteratorObj = arr[Symbol.iterator]("Symbol.iterator");

// // 得到迭代器方法,返回迭代器对象
// console.log(iteratorObj.next());
// console.log(iteratorObj.next());
// console.log(iteratorObj.next());
// console.log(iteratorObj.next());



// /*
//     获取字符串的迭代对象
//     字符串默认部署了Iterator接口,所以可以直接供for of 消费
// */

// let str = "abcdefg"
// for(let item of str){
//     console.log(item)
// }

// var strIteratorObj = str[Symbol.iterator]("Symbol.iterator");

// console.log(strIteratorObj.next()) //  { done: false, value: "a" }
// console.log(strIteratorObj.next()) //  { done: false, value: "b" }
// console.log(strIteratorObj.next()) //  { done: false, value: "c" }
// console.log(strIteratorObj.next()) //  { done: false, value: "d" }

// for(let item of strIteratorObj){
//     console.log(item)       // e f g
// }



// /*
//     for of 中断
//     循环终端会抛出异常,如果循环中断提前退出,会自动调用return 方法,需要注意的是
//     return 方法必须有返回值,且返回值必须是一个object
// */

// var iteratorObj = {
//     items: [100,200,300],
//     [Symbol.iterator]: function(){
//         var self = this;
//         var i = 0;

//         return {
//             next: function(){
//                 var done = (i >= self.items.length);
//                 var value = !done ? self.items[i++] : undefined;

//                 return {
//                     done: done,
//                     value: value
//                 };
//             },
//             return: function(){         // 特定的函数名 return
//                 console.log("提前退出");
//                 return {
//                     // 必须返回一个对象
//                     done: true
//                 }
//             }
//         };
//     }

// }

// for (let item of iteratorObj){
//     console.log(item);
//     if(item === 200){
//         break;
//     }
// }
// // 100  200  提前退出




// /*
//     对于可迭代的对象的理解
//     解构赋值的时候也会默认调用Symbol.iterator 方法
// */

// // 字符串默认部署了iterator迭代方法,可被迭代
// let str = '123456'
// let [a,b] = str
// console.log(a,b)    // 1 2


// // map
// var map = new Map();
// map.set("name", "chenhao");
// map.set("age", 27);
// map.set("height", 187);

// let [name, age] = map
// console.log(name, age)  //  ["name", "chenhao"],["age", 27]

// let [m,n] = { name: "chenhao" }
// console.log(m,n)    // "Uncaught TypeError: {(intermediate value)} is not iterable"


// // 自定义可迭代对象进行解构赋值
// var iteratorObj = {
//     items: ["红", "绿", "蓝"],
//     [Symbol.iterator]: function(){
//         var self = this;
//         var i = 0;
//         return {
//             next(){
//                 var done = (i >= self.items.length);
//                 var value = !done ? self.items[i++] : undefined;

//                 return {
//                     done: done,
//                     value: value
//                 }
//             },
//             return(){
//                 console.log("循环中断")
//                 return {done: true}
//             }
//         }
//     }
// }

// let [c,h] = iteratorObj;
// console.log(c,h)    // "红","绿"
// for(let item of iteratorObj){
//     console.log(item)   
//     if(item === "绿"){
//         break;
//     }
// }           // 红 绿 循环中断






// /*
//     扩展运算符 ... 也会默认调用对象的Symbol.iterator方法,可以将当前迭代对象转换成数组
//     只有默认部署了iterator对象的对象才能使用扩展运算符
// */

// // 字符串
// var str = "1234"
// console.log([...str]);  // ["1", "2", "3", "4"] 


// // map 对象
// var map = new Map([[1,2], [3,4]]);
// console.log([...map]);  //  [[1, 2], [3, 4]]


// // set 对象
// var set = new Set([1,2,3]);
// console.log([...set])   //  [1, 2, 3]


// // 通用对象不可使用运算符转成数组,因为没有默认部署 iterator 方法
// var obj = {name: "chenhao"};
// console.log([...obj]);  //  "Uncaught TypeError: obj is not iterable"


// /*
//     修改数据源的iterator方法
// */

// var arr = [100,200,300];

// arr[Symbol.iterator] = function(){
//     var self = this;
//     var i = 0;
//     return {
//         next(){
//             var done = (i >= self.length);
//             var value = !done ? self[i++] : undefined;

//             return {
//                 done: done,
//                 value: value + '测试数据'
//             }
//         }
//     }
// }


// for(let item of arr){
//     console.log(item)
// }   // "100测试数据" "200测试数据" "300测试数据"  (已覆盖完成)


// /*
//     判断对象是否可迭代(是否部署了Symbol.iterator属性)

// */
// function isIterator(object){
//     return typeof object[Symbol.iterator] === "function";
// }

// console.log(isIterator('abcdefg')); // true
// console.log(isIterator([1,2,3,4])); // true
// console.log(isIterator("Hello")); // true
// console.log(isIterator({})); // false
// console.log(isIterator(true)); // false
// console.log(isIterator(Symbol())); // false
// console.log(isIterator(new Map())); // true
// console.log(isIterator(new Set())); // true
// console.log(isIterator(new WeakMap())); // false
// console.log(isIterator(new WeakSet())); // false



/*
    总结: 
    (1) 已默认部署 Iterator 接口的对象主要包括数组丶字符串丶Set 丶Map 丶类似数组的对象(arguments 对象,DOM NodeList对象)
    (2) Iterator 可以为不同的数据结构提供一种统一的数据访问方式
    (3) for of 执行的时候引擎会自动调用对象的迭代器(iterator)来取值
*/
console 命令行工具 X clear

                    
>
console