ES6-遍历器与for-of循环
一.认识Iterator对象(可遍历对象)
console.log([1, 2]);
console.log([1, 2][Symbol.iterator]);//ƒ values() { [native code] }
console.log([1, 2]['Symbol.iterator']);//undefined 注意这个特殊不能加''
console.log([1, 2]['reverse']);//ƒ reverse() { [native code] }
console.log(Symbol.iterator);//Symbol(Symbol.iterator)
Symbol是ES6新增函数,这里是一个对象,一切皆对象.函数也可以添加属性和方法;
Symbol.iterator是这个数组原型上面的方法,这个数组可以使用他的方法;
// console.log([1, 2][Symbol.iterator]);//ƒ values() { [native code] }
console.log([1, 2][Symbol.iterator]());//Array Iterator {} 得到的是该数组的Iterator对象(可遍历/迭代对象);这个对象的原型上有next方法:
二。使用Iterator
const it = [1, 2][Symbol.iterator]();
console.log(it.next());//{value: 1, done: false}
console.log(it.next());//{value: 2, done: false}
console.log(it.next());//{value: undefined, done: true}
value的1是数组的数组元素1;done属性表示遍历是否完成;把数组里面的成员都遍历完再遍历一次value得到undefined才算遍历完成;
1.可遍历对象:不是任何对象都叫可遍历对象,首先要能使用next方法,且该对象调用next方法返回一个对象,这个对象有value和done属性;
2.Symbol.iterator是可遍历对象生成方法 : [1, 2][Symbol.iterator]() ---->得到该数组的可遍历对象:Array Iterator {} ------>利用next方法遍历数组;
三。什么是iterator: [1, 2][Symbol.iterator]() ---->得到该数组的可遍历对象:Array Iterator {} ------>利用next方法遍历数组,这个过程就是iterator
四。为什么要用iterator遍历方式:因为是统一的遍历方式,下面要讲的for-of循环的底层原理就是使用iterator遍历方式;
五。for-of
1.底层原理
const arr = [1, 2, 3];
const it = arr[Symbol.iterator]();
let next = it.next()
while (!next.done) {
console.log(next.value);// 1 2 3
next = it.next();
}
所以数组之所以可以用for of循环,是因为他可以使用可遍历对象生成方法symbol.iterator
2。使用for-of
const arr = [1, 2, 3];
console.log(arr);
for (const item of arr) {
console.log(item);// 1 2 3
};
①.在for-of中获得数组的索引
arr.keys()得到的就是可遍历对象
arr.keys()和数组一样,他也可以调用可遍历对象生成方法,所以arr.keys()也可以用for of循环,arr.keys()也可以像arr一样写在of后面;
keys()是对键的遍历,这里的键是索引
②.在for-of中获得数组的值,和for-of数组本身没区别
values()是对值的遍历,和直接of数组本身没区别;
③.在for-of中获得数组每一个成员的下标及值组合而成的数组
entries()是对键值对的遍历
第一轮循环const entries =[0,1]------->{const entries=[0,1]...}
第二轮循环{const entries =[1,2]...}
解构赋值
第一轮循环const [index,value] = [ 0,1]------->{const [index,value]=[0,1]...}
第二轮循环{const [index,value] =[1,2]...}
注意:for each 方法没办法和break和continue使用;因为for each是方法不是for循环;
六。原生可遍历 与 非原生可遍历
1.只要有 Symbol.iterator 方法,并且这个方法可以生成可遍历对象,就是可遍历的;
2.数组天生就可以调用Symbol.iterator 方法,生成可遍历对象,所以是原生可遍历;普通对象天生不能调用Symbol.iterator 方法,可以通过自己添加这个方法,达到可遍历,所以通过添加的方式后就是非原生可遍历
3.只要可遍历,就可以使用 for...of 循环来对其统一遍历(该数据调用Symbol.iterator 方法返回可遍历对象,这个对象可以使用next方法,且调用next方法返回一个对象有value和done属性)
4.原生可遍历有哪些:
// for (const item of [1, 2, 3]) {
// console.log(item);//1 2 3
// }
// for (const item of 'hi') {
// console.log(item);//'h' 'i'
// }
// for (const item of new Set([1, 2])) {
// console.log(item);//1 2
// }
for (const item of new Map([['a', 1], ['b', 2], ['a', 3]])) {
console.log(item);// ['a', 3] ['b', 2]
}
6:非原生可遍历:
①一般的对象,我们手动添加可遍历对象生成方法Symbol.iterator,且调用该方法要让他返回可遍历对象(首先要能使用next方法,且该对象调用next方法返回一个对象,这个对象有value和done属性;)
我们手动添加一下:(先留一个问题:既然是手动添加,那么必须用Symbol.iterator、next、value,done这些命名吗?)只要这个对象满足obj[Symbol.iterator]()返回的是可遍历对象(首先要能使用next方法,且该对象调用next方法返回一个对象,这个对象有value和done属性;)
//这里涉及闭包,index局部变量没有被销毁
②有 length 和索引属性的对象
第一种方法:我们手动添加一下可遍历对象生成方法
const obj = {
0: 'a',
1: 'b',
length: 2
}
obj[Symbol.iterator] = function () {
let index = 0;
return {
next() {
let value, done;
if (index < obj.length) {
value = obj[index];
done = false;
} else {
value = undefined;
done = true;
}
index++;
return {
value,
done
}
}
}
}
for (const item of obj) {
console.log(item);//'a' 'b'
}
//由此可知,数组的可遍历对象生成方法底层大概逻辑就是如此
第二种方法,由于这种对象类似类数组对象,有 length 和索引属性,可以直接
console.log(...[1, 2, 3]);
console.log(1, 2, 3);
console.log(...'str');
console.log(...new Set([1, 2, 3]));
// console.log(...{}); ×
const m = new Map([['a', 1], ['b', 2], ['a', 3]]);
console.log(...m);//['a', 3] ['b', 2]
const obj1 = {
a: 1,
b: 2
}
console.log(...obj1);//报错
②当然手动加了可遍历对象生成方法的对象(非原生可遍历)可以按照数组的形式直接展开
const obj = {
0: 'a',
1: 'b',
length: 2
}
obj[Symbol.iterator] = function () {
let index = 0;
return {
next() {
let value, done;
if (index < obj.length) {
value = obj[index];
done = false;
} else {
value = undefined;
done = true;
}
index++;
return {
value,
done
}
}
}
}
console.log(...obj);// 'a' 'b'
2.数组的解构赋值,只要是可遍历的,就可以按照数组的方式解构赋值,即使结构不匹配,但是程序内部会先把解构右边的数据先在数组中展开,再解构
3.Set 和 Map 的构造函数的实参必须满足是可遍历数据,当然Map的实参还须满足体现出键值对;
ES6-遍历器与for-of循环的更多相关文章
- ES6学习笔记(十三)Iterator遍历器和for...of循环
1.概念 遍历器(Iterator)就是这样一种机制.它是一种接口,为各种不同的数据结构提供统一的访问机制.任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有 ...
- ES6遍历器 生成器 学习整理
遍历器[迭代器](Iterator) 就是这样一种机制.它是一种接口,为各种不同的数据结构提供统一的访问机制.任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所 ...
- 【前端】【javascript】es6中的遍历器接口Iterator
好久没发文章啦-.-为了证明我还活着,我决定从笔记里面抓一篇还算不乱比较像文章的发出来... 这些笔记是我在学es6的时候断断续续记录的,最近会一份一份整理陆陆续续发出来,顺便也自己再看一遍.我学习e ...
- Iterator(遍历器) 和 for...of 循环
是generator的前置知识 generator :https://www.cnblogs.com/wangtong111/p/11322961.html 遍历器(Iterator)就是这样一种机制 ...
- Iterator接口(遍历器)和for/of循环
在javascript中表示“集合”的数据结构,主要有Array,Object,Map,Set. Iterator(遍历器)接口是为各种不同的数据结构提供了统一的访问机制.任何数据结构具有Iterat ...
- ES6的 Iterator 遍历器到底是什么?
这节课要讲的是ES6中的Iterator. for...of为啥不遍历Object对象 第十三节我们讲了简单又实用的for...of,我们可以使用它来遍历数组,字符串,Set和Map结构,但是有没有发 ...
- ES6的Iterator遍历器
JS表示集合的对象主要有Array.Set.Object.Map,在以前,遍历它们需要使用2种不同的方法,而现在,JS提出了Iterator机制,可以给不同的数据结构提供统一的遍历方法,就是for…o ...
- iterator [ɪtə'reɪtə] 遍历器
lterator 遍历器 遍历器是一种接口,它为不同的数据结构提供了统一的访问机制. 如果一个数据结构具有遍历器接口,那么就可以依次处理该数据结构的成员. 当前 javascript 用来表示集合的数 ...
- Iterator 遍历器
1.遍历器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制.任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员). 2.Iterator ...
- ES6_08_Iterator遍历器
Iterator遍历器: 概念: iterator是一种接口机制,为各种不同的数据结构提供统一的访问机制 作用: 1.为各种数据结构,提供一个统一的.简便的访问接口: 2.使得数据结构的成员能够按某种 ...
随机推荐
- 【eslint 插件开发】禁用 location 跳转外部链接
背景 公司 h5 项目需要为跳转的外部链接统一增加参数.举个例子,假设有如下代码: location.href = 'https://www.test.com/a?id=xxx' location.r ...
- 冰河指南AI技术社区基于ChatGPT正式启动运营
大家好,我是冰河~~ 最近ChatGPT真的太火了,科技圈几乎都在争相报导这个黑科技,它能够通过学习和理解人们的语言来和人类进行对话,能够与人们进行交流,甚至可以对你提出的问题进行分析,尽可能给出你想 ...
- go 神奇的错误 time.Now().Format("2006-01-02 13:04:05") 比北京时间大8小时
困倦的时候写了个个获取本地时间,打印总比当前时间大8小时,找了很久原因 package main import ( "fmt" "time" ) func ma ...
- Python:Excel自动化实践入门篇 乙【送图书活动继续】
*以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「englyf」https://mp.weixin.qq.com/s/y-npGelPJwmx3iNvHaXRTg 本文上接<Py ...
- pat 乙级1024 科学计数法关于stl中size()的一些思考即测试点六,无符号整数问题
来,先看题目:1024 科学计数法 分数 20 作者 HOU, Qiming 单位 浙江大学 科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9 ...
- 微信小程序分享百度网盘文件的实现思路
需求: 在小程序中点击按钮,获取百度网盘文件的下载地址. 实现思路: 1.网盘文件的下载地址,使用官方API只能自己下载,别人通过dlink无法下载,所以采用网页端生成接口. 好处是可以自定义提取码, ...
- No.2.4
Flex布局 主轴方向:(使用flex-direction改变元素排列方向) 思考:Flex布局模型中,弹性盒子默认沿着哪个方向排列? 水平方向 思考:如何实现内容垂直排列? 修改主轴的方向 主轴默认 ...
- 有趣的drop-shadow
如果写了好几个阴影,filter: drop-shadow(-0.5vmin 6vmin 0 var(--s2)) drop-shadow(-4.5vmin 10vmin 0 var(--v3));将 ...
- Android Studio连接SQLlite
1. MainActivity.java package com.example.dbproject;import android.database.sqlite.SQLiteDatabase;imp ...
- cmake:macro,function中ARGV,ARGN参数的区别
cmake中的宏(macro)和函数(function)都支持动态参数 变量ARGC记录传入的参数个数 变量ARGV0,ARGV1,...顺序代表传入的参数 变量ARGV则是一个包含所有传入参数的li ...