当前位置: 首页 > news >正文

[JavaScript]_[初级]_[关于forof或者for...of循环语句的用法]

场景

  1. 在开发网页时,经常需要枚举NodeList类型的数据,比如通过document.body.childNodes获取的, 通过DOM.querySelectorAll也能获取到NodeList对象。那么这个返回的对象除了for...i方式枚举,还有更快的方法吗?

说明

  1. 枚举NodeList对象,最快的方法就是使用for...of循环语句。 它可以直接枚举出值,不需要再通过索引访问。variable每次迭代都会得到迭代对象的下一个值。variable可以用var,let,const修饰。
for (variable of iterable) {
    //statements
}
  1. 枚举可迭代对象,包括Array,Map,Set,String,TypeArray,arguments对象等。它是的原理是创建一个迭代循环,调用自定义的钩子(yield xx), 返回不同的值。

  2. for...of不能枚举普通的key,value对象类型. {a:"a",b:"b"}.

  3. 迭代完成后,或者通过在循环体里调用break,throw,return,生成器会(function*实例)关闭,因此不要重用生成器。

  4. 只迭代可迭代对象迭代值, 其他属性值不会迭代。

例子

<html>
    <head>
        <style>
            .read{
                color: blue;
            }
            .bold{
                font-weight: 600;
            }
        </style>
    </head>
    <body>
        <p id="out">for...of</p>
    </body>
    <script>
        function print(str){
            let p = document.createElement("p");
            p.innerHTML = str;
            document.body.append(p)
        }

        function printSingleIteratorValue(data){
            for(const p of data)
                print(p);
        }

        function printSinglePropertyValue(data){
            for(const p in data)
                print(`${p}=${data[p]}`);
        }

        print("1. 迭代 Map.");
        let visitData = new Map([["a", 1], ["b", 2], ["c", 3]]);
        for(const p of visitData){
            print(`${p[0]} = ${p[1]}`);
            p[1] = 100; //p是临时变量, 不会影响原来的值。
        }    
        print("-- [key,value] 形式");
        for(const [key,value] of visitData)
            print(`${key} = ${value}`);    
        
        print("2. Array, TypeArray, Set 和 String");
        let visitArray = [10, 20, 30];
        let visitTypeArray = new Uint8Array([0x00, 0xff]);
        let visitSet = new Set([1, 1, 2, 2, 3, 3]);
        let visitString = "Tobey";

        print("-- Array");
        printSingleIteratorValue(visitArray);

        print("-- TypeArray");
        printSingleIteratorValue(visitTypeArray);

        print("-- Set");
        printSingleIteratorValue(visitSet);

        print("-- String");
        printSingleIteratorValue(visitString);


        print("3. 函数参数arguments对象");
        (function(){
            printSingleIteratorValue(arguments);
        })(1,2,3,4);


        print("4. 只枚举可迭代对象的数组迭代值, 非迭代值的属性objCustom,arrCustom,foo不迭代")
        Object.prototype.objCustom = function() {};
        Array.prototype.arrCustom = function() {};

        let iterable = [3, 5, 7];
        iterable.foo = 'hello';
        printSingleIteratorValue(iterable);

        print("-- for...in");
        printSinglePropertyValue(iterable);

        print("5. 迭代自定义生成器,break关闭生成器之后不可用!");
        var gen = (function *(){
            yield 1;
            yield 2;
            yield 3;
        })();

        for (let o of gen) {
            print(o);
            break;//关闭生成器
        }

        
        print("-- 生成器不应该重用,以下不会输出。");
        for (let o of gen) 
            print(o);
        

        print("6. 迭代DOM集合, NoteList对象");
        let ps = document.querySelectorAll("p");
        print("-- 增加字体蓝色样式");
        for(let one of ps)
            one.classList.add("read")
        
        print("-- 增加粗体样式");
        for(let i = 0; i<ps.length; i++)
            ps[i].classList.add("bold");
        

    </script>
</html>

输出

for...of

1. 迭代 Map.

a = 1

b = 2

c = 3

-- [key,value] 形式

a = 1

b = 2

c = 3

2. Array, TypeArray, Set 和 String

-- Array

10

20

30

-- TypeArray

0

255

-- Set

1

2

3

-- String

T

o

b

e

y

3. 函数参数arguments对象

1

2

3

4

4. 只枚举可迭代对象的数组迭代值, 非迭代值的属性objCustom,arrCustom,foo不迭代

3

5

7

-- for...in

0=3

1=5

2=7

foo=hello

arrCustom=function() {}

objCustom=function() {}

5. 迭代自定义生成器,break关闭生成器之后不可用!

1

-- 生成器不应该重用,以下不会输出。

6. 迭代DOM集合, NoteList对象

-- 增加字体蓝色样式

-- 增加粗体样式

参考

  1. for…of - JavaScript | MDN

  2. HTML DOM 元素对象

  3. HTML DOM querySelectorAll() 方法

相关文章:

  • matlab gui设计入门与实战,matlab gui编程教程
  • 基于Bootstrap+Django+Python的点菜信息管理系统
  • PCIe序与死锁
  • npm 和 yarn 命令对照表
  • Springboot整合ES8(Java API Client)
  • GB/T 28181联网系统通信协议结构和技术实现
  • 使用 Spark Java 框架构建 API
  • 【文献导读】XPBD: Position-Based Simulation of Compliant Constrained Dynamics
  • 直流有刷电机转速、电流双闭环调速系统及Matlab/Simulink仿真分析
  • 诡异错误 Unresolved reference: styleable
  • exception错误处理库学习
  • 蔚来、小鹏、吉利走到了跨界分叉口
  • 神卓互联SDWAN技术实现异地组网办公(无需硬件)
  • Redis分布式锁(下篇)
  • Vue--整合SVG Icon图标--方法/实例
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • C学习-枚举(九)
  • Javascript基础之Array数组API
  • leetcode388. Longest Absolute File Path
  • scala基础语法(二)
  • vue-router 实现分析
  • 分享几个不错的工具
  • 简单实现一个textarea自适应高度
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 为什么要用IPython/Jupyter?
  • 小程序button引导用户授权
  • 用 Swift 编写面向协议的视图
  • 用jQuery怎么做到前后端分离
  • 原生js练习题---第五课
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​什么是bug?bug的源头在哪里?
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #大学#套接字
  • (1)STL算法之遍历容器
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (vue)页面文件上传获取:action地址
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (转)visual stdio 书签功能介绍
  • (转)大道至简,职场上做人做事做管理
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .NET6 开发一个检查某些状态持续多长时间的类
  • @Resource和@Autowired的区别
  • @SuppressLint(NewApi)和@TargetApi()的区别
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [<死锁专题>]
  • [Android] Amazon 的 android 音视频开发文档
  • [BZOJ1053][HAOI2007]反素数ant
  • [BZOJ4554][TJOI2016HEOI2016]游戏(匈牙利)
  • [Codeforces] probabilities (R1600) Part.1