ES6-Iterators-改变不能遍历迭代的对象使之可以迭代

35次阅读

共计 4008 个字符,预计需要花费 11 分钟才能阅读完成。

参考:https://segmentfault.com/a/11…

遍历迭代数据最寻常的就是数组

在某些情况下,希望返回数组中的所有单独值,以便在屏幕上打印它们、操作它们或对它们执行某些操作。

如何处理?简单方法就是使用 for, while, for-of 方法。

const myFavouriteAuthors = [
         'Neal Stephenson',
         'Arthur Clarke',
         'Isaac Asimov', 
         'Robert Heinlein'
       ]
       for(let i =0;i<myFavouriteAuthors.length; i++){console.log(myFavouriteAuthors[i])
       }
        let  index = 0;
        while(index<myFavouriteAuthors.length){console.log(myFavouriteAuthors[index])
          index++
        }
        for(let value of myFavouriteAuthors){console.log(value)
        }
        
        
        
       
       created(){this.func()
    
    },
    methods:{func(){
        const myFavouriteAuthors = {
          allAuthors:{
            function: [
         'Neal Stephenson',
         'Arthur Clarke',
         'Isaac Asimov', 
         'Robert Heinlein'
          ],
          scienceFiction:[
         'Neal Stephenson',
         'Arthur Clarke',
         'Isaac Asimov', 
         'Robert Heinlein'
       ],
       fantasy:[
         'Neal Stephenson',
         'Arthur Clarke',
         'Isaac Asimov', 
         'Robert Heinlein'
       ]
          },
          getAllAuthors(){const othors = []
            for(const othor of this.allAuthors.function){othors.push(othor)
            }
            for(const othor of this.allAuthors.scienceFiction){othors.push(othor)
            }
            for(const othor of this.allAuthors.fantasy){othors.push(othor)
            }
            return othors
          }
          
        }
        console.log(myFavouriteAuthors.getAllAuthors())
      }
    }
        

可迭代

可迭代是一种数据结构,它希望使其元素对外部可访问,通过实现一个关键字是 Symbol.iterator 的方法来实现,该方法是迭代器的工厂,也就是说,它将创建迭代器。
迭代器是一个指针,用于遍历数据结构的元素,我们将使用 computed property 语法来设置这个键,如下:

created(){this.func()
    
    },
    methods:{func(){
         const iterable = {[Symbol.iterator](){ // 我们创建迭代器。它是一个定义了 next 方法的对象。let step = 0
             const iterator = {next(){ // next 方法根据 step 变量返回值。step++;
                 if(step==1){return {value:'This',done: false};
                 }else if(step ==2){return { value:'is',done: false}
                 }else if(step ==3){return {value:'iteable',done: false}
                 }
                 return {value: Undefined,done: true}
               }
             }
             return iterator
           }
         }
         var iterator = iterable[Symbol.iterator]()
         console.log(iterator.next())
         console.log(iterator.next())
         console.log(iterator.next())
         console.log(iterator.next())
        //  {value: "This", done: false}
        //  {value: "is", done: false}
        //  {value: "iteable", done: false}
        //  {value: Undefined, done: true}
        我们检索 iterator, 调用 next 方法,直到 done 的值为 true。}
    }
  }

这正是 for-of 循环中发生的事情,for-of 接受一个迭代器,并创建它的迭代器, 它会一直调用 next(),直到 done 为 true。

数组解构 — 由于可迭代性,会发生析构。

const array = ['a','b','c','d','e']
         const [first,third,last] = array
         console.log(first)//a
         
         
         等价于:

         const array = ['a','b','c','d','e']
         const iterator = array[Symbol.iterator]()
         const first = iterator.next().value
         console.log(first)//a
         const third = iterator.next().value
         console.log(third)//b
         const last = iterator.next().value
         console.log(last)//c
         

扩展操作符 (…)

const array = ['a','b','c','d','e']
         const newArray = [1,...array,2,3]
         console.log(newArray)//[1, "a", "b", "c", "d", "e", 2, 3]
         
    
    等价于
       const array = ['a','b','c','d','e']
         const iterator = array[Symbol.iterator]()
         const newArray = [1]
         
         for(let nextValue = iterator.next();nextValue.done !== true;nextValue = iterator.next()){newArray.push(nextValue.value)
         }
         newArray.push(2)
         newArray.push(3)
         console.log(newArray) //[1, "a", "b", "c", "d", "e", 2, 3] 

JS 中的很多对象都是可迭代的。它们可能不是很好的察觉,但是如果仔细检查,就会发现迭代的特征:

Arrays and TypedArrays
Strings —— 遍历每个字符或 Unicode 代码点
Maps —— 遍历其键 - 值对
Sets —— 遍历元素
arguments  —— 函数中类似数组的特殊变量
DOM elements (Work in Progress)
JS 中使用迭代的其他一些结构是:

for-of — for-of 循环需要一个可迭代的对象,否则,它将抛出一个类型错误。
所以我们可以将不能迭代的对象用 iterator 处理一下

mounted() {
    const myFavouriteAuthors = {
     allAuthors: {
     fiction: [
      'Agatha Christie', 
      'J. K. Rowling',
      'Dr. Seuss'
    ],
    scienceFiction: [
      'Neal Stephenson',
      'Arthur Clarke',
      'Isaac Asimov', 
      'Robert Heinlein'
    ],
    fantasy: [
      'J. R. R. Tolkien',
      'J. K. Rowling',
      'Terry Pratchett'
    ],
  },
  [Symbol.iterator]() {
    // 获取数组中的所有作者
    const genres = Object.values(this.allAuthors);
    //Object.values() 方法返回一个给定对象自身的所有可枚举属性值的数组,// 存储当前类型和索引
    let currentAuthorIndex = 0;
    let currentGenreIndex = 0;
    
    return {// Implementation of next()
      next() {
        // 根据当前的索引获取对应的作者信息
        const authors = genres[currentGenreIndex];
        
        // 当遍历完数组 authors 时,doNotHaveMoreAuthors 为 true
        const doNothaveMoreAuthors = !(currentAuthorIndex < authors.length);
        console.log(currentAuthorIndex, authors.length, doNothaveMoreAuthors);
        if (doNothaveMoreAuthors) {
         // 加一继续访问下一个
          currentGenreIndex++;
          // 重置
          currentAuthorIndex = 0;
        }
        
        // 如果所有 genres 都遍历完了结,那么我们需要告诉迭代器不能提供更多的值。const doNotHaveMoreGenres = !(currentGenreIndex < genres.length);
        if (doNotHaveMoreGenres) {
          return {
            value: Undefined,
            done: true
          };
        }
        
        // 如果一切正常,从当 genre 返回 作者和当前作者索引,以便下次,下一个作者可以返回。return {value: genres[currentGenreIndex][currentAuthorIndex++],
          done: false
        }
      }
    };
  }
};

for (const author of myFavouriteAuthors) {console.log(author);
}

console.log(...myFavouriteAuthors)


  }

正文完
 0