一、for....of

  1.for…of是作为ES6新增的遍历方式,允许遍历一个含有iterator接口的数据结构(数组、对象等)并且返回各项的值,普通的对象用for…of遍历是会报错的。

  2.for...of 循环只能用来遍历数组、类数组对象,字符串、Set、Map 以及 Generator 对象

二、for...in(遍历出来的都为可枚举属性)

  1.for...in 循环主要是为了遍历对象可枚举属性而生,不推荐于遍历数组,遍历数组返回的是数组索引

三、可枚举属性

  1.用户定义的属性都是可枚举的,而内置对象不可枚举

  2.obj.name、obj.prototype.name添加的属性可枚举,defineProperty不可枚举

1、for...in 循环:只能获得对象的键名,不能获得键值

for...of 循环:允许遍历获得键值

  1. var arr = ['red', 'green', 'blue']
  2.  
  3. for(let item in arr) {
  4. console.log('for in item', item)
  5. }
  6. /*
  7. for in item 0
  8. for in item 1
  9. for in item 2
  10. */
  11.  
  12. for(let item of arr) {
  13. console.log('for of item', item)
  14. }
  15. /*
  16. for of item red
  17. for of item green
  18. for of item blue
  19. */

2、对于普通对象,没有部署原生的 iterator 接口,直接使用 for...of 会报错

  1. var obj = {
  2. 'name': 'Jim Green',
  3. 'age': 12
  4. }
  5.  
  6. for(let key of obj) {
  7. console.log('for of obj', key)
  8. }
  9. // Uncaught TypeError: obj is not iterable

可以使用 for...in 循环遍历键名

  1. for(let key in obj) {
  2. console.log('for in key', key)
  3. }
  4. /*
  5. for in key name
  6. for in key age
  7. */

也可以使用 Object.keys(obj) 方法将对象的键名生成一个数组,然后遍历这个数组

  1. for(let key of Object.keys(obj)) {
  2. console.log('key', key)
  3. }
  4. /*
  5. key name
  6. key age
  7. */

3、for...in 循环不仅遍历数字键名,还会遍历手动添加的其它键,甚至包括原型链上的键。for...of 则不会这样

  1. let arr = [1, 2, 3]
  2. arr.set = 'world' // 手动添加的键
  3. Array.prototype.name = 'hello' // 原型链上的键
  4.  
  5. for(let item in arr) {
  6. console.log('item', item)
  7. }
  8.  
  9. /*
  10. item 0
  11. item 1
  12. item 2
  13. item set
  14. item name
  15. */
  16.  
  17. for(let value of arr) {
  18. console.log('value', value)
  19. }
  20.  
  21. /*
  22. value 1
  23. value 2
  24. value 3
  25. */

4、forEach 循环无法中途跳出,break 命令或 return 命令都不能奏效

  1. let arr = [1, 2, 3, 5, 9]
  2. arr.forEach(item => {
  3. if(item % 2 === 0) {
  4. return
  5. }
  6. console.log('item', item)
  7. })
  8. /*
  9. item 1
  10. item 3
  11. item 5
  12. item 9
  13. */

for...of 循环可以与break、continue 和 return 配合使用,跳出循环

  1. for(let item of arr) {
  2. if(item % 2 === 0) {
  3. break
  4. }
  5. console.log('item', item)
  6. }
  7. // item 1

5、无论是 for...in 还是 for...of 都不能遍历出 Symbol 类型的值,遍历 Symbol 类型的值需要用 Object.getOwnPropertySymbols() 方法

  1. {
  2. let a = Symbol('a')
  3. let b = Symbol('b')
  4.  
  5. let obj = {
  6. [a]: 'hello',
  7. [b]: 'world',
  8. c: 'es6',
  9. d: 'dom'
  10. }
  11.  
  12. for(let key in obj) {
  13. console.info(key + ' --> ' + obj[key])
  14. }
  15.  
  16. /*
  17. c --> es6
  18. d --> dom
  19. */
  20.  
  21. let objSymbols = Object.getOwnPropertySymbols(obj)
  22. console.info(objSymbols) //  [Symbol(a), Symbol(b)]
  23. objSymbols.forEach(item => {
  24. console.info(item.toString() + ' --> ' + obj[item])
  25. })
  26.  
  27. /*
  28. Symbol(a) --> hello
  29. Symbol(b) --> world
  30. */
  31.  
  32. // Reflect.ownKeys 方法可以返回所有类型的键名,包括常规键名和Symbol键名
  33. let keyArray = Reflect.ownKeys(obj)
  34. console.log(keyArray) //  ["c", "d", Symbol(a), Symbol(b)]
  35. }

for in 和 for of 的区别(枚举解释)的更多相关文章

  1. apt与apt-get命令的区别与解释

    [apt与apt-get命令的区别与解释] Ubuntu 16.04 发布时,一个引人注目的新特性便是 apt 命令的引入.其实早在 2014 年,apt 命令就已经发布了第一个稳定版,只是直到 20 ...

  2. IEnumerable< T >和IEnumerable区别 |枚举接口

    为什么我们在继承IEnumerable< T >接口的时候也要实现IEnumerable接口. 新的代码里面都用IEnumerable< T >,因为泛型的类型是安全的.我们可 ...

  3. 管道命令和xargs的区别(经典解释)

    一直弄不懂,管道不就是把前一个命令的结果作为参数给下一个命令吗,那在 | 后面加不加xargs有什么区别 NewUserFF 写道: 懒蜗牛Gentoo 写道: 管道是实现"将前面的标准输出 ...

  4. Linux中apt与apt-get命令的区别与解释

    2019-01-15 14:35:39 随着 apt install package 命令的使用频率和普遍性逐步超过 apt-get install package,越来越多的其它 Linux 发行版 ...

  5. (转载)管道命令和xargs的区别(经典解释)

    一直弄不懂,管道不就是把前一个命令的结果作为参数给下一个命令吗,那在 | 后面加不加xargs有什么区别 NewUserFF 写道:懒蜗牛Gentoo 写道:管道是实现“将前面的标准输出作为后面的标准 ...

  6. 管道命令和xargs的区别(经典解释) 自己的总结

    1. 简介 之所以能用到这个命令,关键是由于很多命令不支 持|管道来传递参数,而日常工作中有有这个必要, 所以就有了xargs命令,例如:find /sbin -perm +700 |ls -l 这个 ...

  7. 对std::string和std::wstring区别的解释,807个赞同,有例子

    807down vote string? wstring? std::string is a basic_string templated on a char, and std::wstring on ...

  8. PO,VO,DAO,BO,POJO之间的区别与解释

    VO value object:值对象 通常用于业务层之间的数据传递,由new创建,由GC回收. PO persistant object:持久层对象 对应数据库中表的字段. VO和PO,都是属性加上 ...

  9. Java 中 VO、PO、DTO、BO、POJO、DAO 之间的区别与解释

    转载:https://www.cnblogs.com/hunmeng/p/11298680.html VO value object:值对象 通常用于业务层之间的数据传递,由new创建,由GC回收. ...

  10. Java之枚举

    1.定义 enum 是一种数据类型,与 全局常量比较相似,都是全局的并且是可以通过类名调用的 与全局常量区别 枚举功能更强大,可以有属性和方法 枚举比全局常量更加的规范 2.枚举特性 1)可以有属性以 ...

随机推荐

  1. js中的Object.keys、array.map、groupBy、call、apply总结分享

    分享几个js中的函数 Object.keys() 首先这个函数是用来干嘛的呢?是用来把一个json字符串里的key全都取出来重新整成一个数组的方法,那么这个函数怎么用呢,接下来贴出我最近碰见的用法: ...

  2. AC 自动机上 DP

    \(\text{Analysis}\) 做了几道题后发现挺套路的 涉及统计或构造文本串与众多模式串匹配产生贡献或存在限制时的 \(DP\) 一般设 \(f[i][j]\) 表示考虑到文本串第 \(i\ ...

  3. Ubuntu18.04安装教程

    转载csdn: Ubuntu18.04安装教程_Sunshine的博客-CSDN博客_ubuntu安装教程

  4. 在wifi的5G频率下无法加载图片解决方法

    开始是这样的:因为我家wifi支持300兆的网速,所以换了一个荣耀的路由器,换了一根网线,但是发现5G频率有的应用加载不了图片,所以查了很多资料想了很多办法,终于解决了, 解决方法如下: 1.这是DH ...

  5. Bulldog

    Bulldog 目录 Bulldog 1 信息收集 1.1 端口扫描 1.2 后台目录扫描 1.2.1 目录分析 2 Web-Shell利用 2.1 尝试命令执行 2.2 尝试利用系统命令注入 2.3 ...

  6. SQL语句中 left join 后用 on 还是 where,区别大了!

    前天写SQL时本想通过 A left B join on and 后面的条件来使查出的两条记录变成一条,奈何发现还是有两条. 后来发现 join on and 不会过滤结果记录条数,只会根据and后的 ...

  7. 四川九联代工M301H hi3798 mv300 mt7668魔百和 强刷和TTL线刷(救砖)经验分享

    以下都是本次自己操作后的一些经验,不是技术分享,也是看来很多水教程后总结的精华. 四川九联代工M301H hi3798 mv300 mt7668魔百和  一.强刷 1.强刷的教程网上有很多,自己百度. ...

  8. IDEA插件Apifox,一键自动生成接口文档!

    有关Apifox软件之前写过一篇文章: 接口测试神器Apifox,亲测好用! 如何一键自动生成数据库文档之前也写过一篇文章: 数据库界的Swagger:一键生成数据库文档! 一.Apifox插件的优势 ...

  9. ChatGpt聊天API使用

    昨天ChatGpt发布了聊天API,新增了两个模型,目前还是测试阶段 gpt-3.5-turbo 功能强大的GPT-3.5模型,专门针对聊天做了优化 gpt-3.5-turbo-0301 此模型只支持 ...

  10. ubuntu20.04安装fastdfs遇到的问题

    说明:git clone在线安装与离线安装都不成功后,选择原来可以正常运行的fastdfs服务,进行tar打包下载,再在新项目上进行解压部署.但由于打包压缩动态库的软连接 失效,所以启动出现如下报错信 ...