初学者跪着学JavaScript Day28 : 学迭代,学习不等待

一日客语:中文:报纸 客语:bo ziiˋ

最近很疑惑迭代物件和可迭代到底是什麽??於是查一下资料,发现很有趣

哪些可以迭代?

ArraySetMapString

能使用for/of回圈来迭代


使用:一般物件

不可以迭代

let obj = {
    name: 'wendy',
    age: 18,
    [Symbol.iterator]: '励志成为迭代物件',
};
for (let x of obj) {
    console.log(x);
}

//TypeError: obj is not iterable

使用阵列

可以迭代

let myArray = ['wendy', 20, 30];
for (let x of myArray) {
    console.log(x);
}
//wendy
//20
//30

会什麽会这样呢?明明都是物件居然搞差别待遇!!!/images/emoticon/emoticon16.gif


先说说概念

图例说明:

开始介绍他们

  • iterable object 可迭代物件: Array、 Set、 Map (可迭代的型别)

  • iterator object 迭代器物件 (自己本身可以迭代)

  • iteration object 迭代结果物件 (存放迭代每步骤的结果

不管是中文还是英文,名字长超像一开始很容易搞混!!


可迭代物件( iterable object)

具有 Symbol.iterator 的属性,会回传迭代器物件

可以使用 for/of 来迭代

能使用 spread 展开运算子

能使用解构赋值( Destructuring assignment )

let myArray = [10, 20];//可迭代物件
let myArrayIterator = myArray[Symbol.iterator]();

console.log(myArrayIterator); 
//Object [Array Iterator] {}

let mySet = new Set([1, 2]);//可迭代物件
console.log(mySet[Symbol.iterator]());
//[Set Iterator] { 1, 2 }

let myMap = new Map([
    [1, 'wendy'],
    [2, 'nick'],
    ['red', 'apple'],
]);
console.log(myMap[Symbol.iterator]()); 
//[Map Entries] { [ 1, 'wendy' ], [ 2, 'nick' ], [ 'red', 'apple' ] }

//使用不可迭代物件

let myNumber = 10;
console.log(myNumber[Symbol.iterator]); //undefined
let myObj = { 1: 'wendy', 2: 'ann' };
console.log(myObj[Symbol.iterator]); //undefined



迭代器物件 iterator object

具有 next()方法的物件,使用此 methods 会回传迭代器结果物件

执行可迭代物件的 [Symbol.iterator] 的function

myArray[Symbol.iterator]()

回传是一个迭代器 (iterator object) Array Iterator

怎麽知道他是迭代器物件? 因为他有 next()!!!!/images/emoticon/emoticon07.gif

迭代结果物件 iteration object

物件里具有 value 和 done 的属性

所以输入myArray[Symbol.iterator]().next() 会出现

{
    value:xxx,
    done:false
}

let myArray = [10, 20];
let myIterator = myArray[Symbol.iterator]();
console.log(myIterator.next());//{ value: 10, done: false }
console.log(myIterator.next());//{ value: 20, done: false }
console.log(myIterator.next());//{ value: undefined, done: true }

迭代器可以透过 next(),一直产生出序列值

图片出处:A Simple Guide to ES6 Iterators in JavaScript with Examples

如何做出可迭代物件

可迭代物件要有 [Symbol.iterator] 属性,就可以使用 for / in 制作

一般物件无法迭代,直接报错了

let obj = {
    name: 'wendy',
    age: 18,
    goal: '励志成为迭代物件',
};
for (let x of obj) {
    console.log(x);
}

//TypeError: obj is not iterable

想成为迭代器吗?

物件自己加一个 [Symbol.iterator] 属性然後根据前面讲述,把要求的条件加入

1.要有 next()
2.要有一个物件 {next:xxx,done:true/false}

let myObj = {
    name: 'wendy',
    age: 18,
    hair: 'black',
    [Symbol.iterator]: function () {
        let index = 0;
        let values = Object.values(this);
        return {
            next: () => ({ value: values[index++],
            done: index > values.length }),
        };
    },
};

let iterator = myObj[Symbol.iterator]();
console.log(iterator.next());//{ value: 'wendy', done: false }
console.log(iterator.next());//{ value: 18, done: false }
console.log(iterator.next());//{ value: 'black', done: false }
console.log(iterator.next());//{ value: undefined, done: true }

for (let y of myObj) {
    console.log(y);
}
//wendy
//18
//black

就可以做出自制迭代器, wow 是不是很棒啊,虽然有点废,用 Object.values 就可以

但还是很开心做出来~

Make your objects iterable

是根据这篇大大自制迭代物件,来改写

所以要做出可迭代物件就要手刻,但在ES6出现新语法生成器 (generator) 新定义的迭代器

function* animal() {
    yield 100;
    yield 200;
    yield 'wendy';
}

let genAnimal = animal();
console.log(genAnimal.next().value); //100
console.log(genAnimal.next().value); //200
console.log(genAnimal.next().value); //wendy
console.log(genAnimal.next().value); //undefined

for (x in genAnimal) {
    console.log(x);  
}
    //100
    //200
    //wendy
    //undefined

初学者跪着学JavaScript Day26:认识生成器,chris不生气

读完之後发现原来常用迭代方式背後原理是这样

铁人赛剩两天~撒花/images/emoticon/emoticon42.gif


资料参考:
Make your objects iterable
JavaScript大全第七版
mdn
A Simple Guide to ES6 Iterators in JavaScript with Examples
谢谢array同学


<<:  Day 28. 解掉bug了

>>:  我买开发板了

C# 入门之运算符(补充)

我们前面讲过一些 C# 中的运算符,如,加、减,等等。今天我们补充两个特殊的运算符,is 和 as ...

Day12 同步状态控制 Synchronizer

由於我们可藉由产生带重叠范围的配对请求,而这些配对请求将并发(Concurrently)的触发 MM...

CRC-8-CCITT

CRC-8-CCITT SMBus PEC /* https://en.wikipedia.org/...

Day04 - 【入门篇】浅谈身份验证与授权(2)

本系列文之後也会置於个人网站 实际上,在昨天已经将多数基础都已经解释过了,不过我想到还有一些东西可...

[Day21] 你问我爱你有多深? 用Python让手指爱心超进化!

之前用MediaPipe做过侦测到中指就打马赛克的主题, 下方有朋友留言提议能不能做「侦测到爱心就放...