参考:https://segmentfault.com/a/11...
遍历迭代数据最寻常的就是数组
在某些情况下,希望返回数组中的所有单独值,以便在屏幕上打印它们、操作它们或对它们执行某些操作。
如何处理? 简单方法就是使用 for, while, for-of 方法。
const myFavouriteAuthors = [
'Neal Stephenson',
'Arthur Clarke',
'Isaac Asimov',
'Robert Heinlein'
]
for(let i =0;i
可迭代
可迭代是一种数据结构,它希望使其元素对外部可访问,通过实现一个关键字是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)
}