如果您已经用JavaScript或任何语言编程了一段时间,for-循环对你来说不应该陌生.您没有注意到许多编程语言,包括JavaScript,已经从使用for-循环使用迭代器-返回给定集合的下一项的对象。此外,迭代器使我们的生活在使用集合时变得更容易和更有效率。这就是为什么理解JavaScript迭代器对每个开发人员都有好处,并将在本文中探讨这个主题。好吧,那我们开始吧。

背景

在开始之前,最好先阅读JavaScriptSymbols,你可以在这里查看我的帖子:JavaScript符号基础。原因之一是我们可能会发现Symbol.iterator。请注意,JavaScript迭代器不会替换for-循环和/或其他循环结构。然而,迭代器的主要目标是消除循环的复杂性和易出错性。

目录

  • 不同的循环构造了缺点。

    • 换环
    • Array.forEach
    • 输入循环
    • For-of循环
  • 迭代协议

    • 迭代协议的类型?
    • 什么是迭代器协议?
    • 什么是可迭代协议?
  • Iterator内置类型

    • 检查对象/类型是否实现Symbol.iterator
    • 内置迭代器看起来如何?
    • 迭代器内置类型的快速示例
      • 阵列迭代器
      • 字符串迭代器
      • 集合迭代器

不同的循环构造缺陷

换环

For循环是学习任何编程语言(包括JavaScript)的关键之一。通常,在处理数组时,您通常会使用for循环遍历数据元素。

下面是一个示例:

/*simple loop*/ let dogsName = ['Tank', 'Diesel', 'Cooper', 'Bruno', 'Thor']; for (let index = 0; index < dogsName.length; index++) { console.log(dogsName[index]); } /*end of simple loop*/

我知道,代码示例非常简单。如何创建一个复杂的呢?

/*complex loop*/ let x = 100; for (let i = 0; i <= x; i++) { for (let j = 1; (j + x / 2) < x; j++) { for (let k = 1; k <= x; k++) { console.log("hello"); } } } /*end of complex loop*/

当嵌套循环导致跟踪循环中的多个变量时,复杂性会增加。因此,这会使您的循环容易出错.

Array.forEach

然而,为什么要使用for-循环,如果要迭代数据项,对吗?Array.forEach去营救,不完全是。为什么?在我们回答之前,让我们先看一个例子。

/*forEach loop*/ let amounts = [1.25, 2.25, 3.25, 4.25]; /** * Outputs: * 1.25 * 2.25 * 3.25 * 4.25 */ amounts.forEach((item) => { console.log(item); }); /*end of forEach loop*/

现在回到问题上。因为使用Array.forEach循环不给您在循环构造中中断的能力。

下面是一个示例:

/*forEach loop*/ let amounts = [1.25, 2.25, 3.25, 4.25]; amounts.forEach((item) => { if (item === 3.25) { break; //throws an error: "Uncaught SyntaxError: Illegal break statement" } }); /*end of forEach loop*/

输入循环

当您只对获取对象的这些属性感兴趣时,怎么样?这个for-in循环来救援了。

让我们看看下面的一个例子。

/** Start of for-in loop */ let customer = { firstName: "Jin Vincent", lastName: "Necesario", country: "Philippines" }; /** * Output: * firstName * lastName * country */ for (let key in customer) { console.log(key); } /** End of for-in loop */

但是,for-in循环只能迭代可枚举的非符号属性.因此,迭代一个Array其中索引顺序是重要的。

让我们看看下面的一个例子。

/** Start of for-in loop that iterates over an Array */ /** Warning: Please don't do this on your project/product! */ Array.prototype.bar = 1; let products = [1001, "mouse", "monitor", { firstName: "Jin Vincent" }]; /**Output: * 0 * 1 * 2 * 3 * bar */ for (let prop in products) { console.log(prop); //this outputs the index of the array and bar } /** End of for-in loop that iterates over an Array*/

For-of循环

如果您想迭代数组或集合,并且不介意索引,for-of循环可以节省时间。

您可以使用for-of循环使用实现可迭代协议的对象或集合。

本文后半部分将更多地介绍可迭代协议。

让我们看看下面的一个例子。

/** Start of for of loop */ const xmenGoldTeam = ['Storm', 'Bishop', 'Colossus', 'Jean Grey', 'Iceman', 'Archangel']; /**Outputs: * Storm * Bishop * Colossus * Jean Grey * Iceman * Archangel */ for (let xmen of xmenGoldTeam) { console.log(xmen); } /** end of for of loop */

因此,当对象不可迭代时,不能使用for-of循环来迭代属性。

下面是一个示例:

/** Start of for-of loop */ let customers = { firstName: "Jin Vincent", lastName: "Necesario", country: "Philippines" }; for (const customer of customers) { //TypeError: customers is not iterable } /** End of for-of loop */

迭代协议

基本上,迭代协议是对象在实现接口时需要遵循的一组规则。换句话说,当使用某个协议(可以是可迭代的或迭代器)时,对象应该实现以下功能并使用某种规则。

迭代协议类型

  • Iterator协议
  • 可迭代协议

什么是Iterator协议?

实现迭代器协议时,您应该遵循以下约定:

  • 对象应该实现.next()方法。
  • 这个.next()方法必须返回包含下列属性的对象:value和done.

简而言之,当对象提供next()方法,该方法以具有两个属性的一组项的顺序返回下一项。

这两个属性是完成和值。

  • done-布尔类型,指示是否存在可迭代的现有元素
  • value-当前要素

让我们看看下面的例子,并遵循惯例。

/*Start of an iterator protocol*/ const countries = { collection: ["Philippines", "Singapore", "Malaysia", "Canada", "Brazil", "Australia"], index: 0, next: function () { if (this.index < this.collection.length) { return { value: this.collection[this.index++], done: false } } else { return { done:true } } } } console.log(countries.next()); //output: {value: "Philippines", done: false} console.log(countries.next()); //output: {value: "Singapore", done: false} console.log(countries.next()); //output: {value: "Malaysia", done: false} console.log(countries.next()); //output: {value: "Canada", done: false} console.log(countries.next()); //output: {value: "Brazil", done: false} console.log(countries.next()); //output: {value: "Australia", done: false} console.log(countries.next()); //output: {done: true} /*End of an iterator protocol*/

什么是可持续协议?

在开始之前,需要指出的一点是,JavaScript确实有众所周知的符号,这些符号通常使用@@符号。就像Symbol.iterator,该符号称为@@iterator.

现在回到可迭代协议。当对象实现@@iterator方法被认为是可迭代的。此外,此方法返回迭代器。对象的属性@@iterator可通过Symbol.iterator.

让我们看一个例子来理解上面的语句。

/*Start of an iterable protocol*/ const countries = { countryCollection: ["Philippines", "Singapore", "Malaysia", "Canada", "Brazil", "Australia"], startIndex: 0, [Symbol.iterator]: function () { return { collection: this.countryCollection, index: this.startIndex, next: function () { if (this.index < this.collection.length) { return { value: this.collection[this.index++], done: false } } else { return { done: true } } } } } } let countryIterator = countries[Symbol.iterator](); console.log(countryIterator.next()); //output: {value: "Philippines", done: false} console.log(countryIterator.next()); //output: {value: "Singapore", done: false} console.log(countryIterator.next()); //output: {value: "Malaysia", done: false} console.log(countryIterator.next()); //output: {value: "Canada", done: false} console.log(countryIterator.next()); //output: {value: "Brazil", done: false} console.log(countryIterator.next()); //output: {value: "Australia", done: false} console.log(countryIterator.next()); //output: {done: true} /** * Outputs: * Philippines * Singapore * Malaysia * Canada * Brazil * Australia * undefined */ for (country of countries) { console.log(country) } /*End of an iterable protocol*/

现在我们已经了解了什么是迭代器和可迭代协议,以及for-of循环开始发挥作用。为什么不检查并学习可迭代的内置类型呢?

Iterator内置类型

JavaScript语言有内置的可迭代类型,但我们不会涵盖所有内容,但我们将讨论String, Array,和Set.

对于可迭代内置类型的完整列表,如下所示:

  • String
  • Array
  • Map
  • Set
  • TypedArray
  • 参数对象

检查对象/类型是否实现Symbol.iterator

/** Start of how to check if a type/object implements the Symbol.iterator */ let programmingLanguage = "JavaScript"; //let's us check if the built-in data-type String implements Symbol.iterator //output: [Symbol(Symbol.iterator)] Object.getOwnPropertySymbols(programmingLanguage.__proto__); /** end of how to check if type/object implements the Symbol.iterator */

如您所见,上面的代码示例显示String数据类型确实实现了@@iterator。因此,Strings是可迭代的。

内置的迭代器看起来怎么样?

让我们直接看一个例子,看看迭代器是什么样的。

//declare a JavaScript string type let programmingLanguage = "JavaScript"; //lets invoke the method having an @@iterator property key let iterator = programmingLanguage[Symbol.iterator](); //let's check if the @@iterator property function return an iterator console.log(iterator); //output: StringIterator

如您所见,在上面的示例中,我们已经声明了String类型并调用@@iterator键符号,并检查函数是否真的返回迭代器,并且它确实返回了StringIterator.

Iterator内置类型的快速示例

我们不会详细讨论,因为我们已经讨论了上面的概念。然而,这里的目标是展示我们如何与内置迭代器交互。

阵列迭代器

这个@@iterator方法是可迭代协议的一部分,该协议定义如何遍历项。

const pets = ["Andy", "Barkley", "Zandro"]; const petIterator = pets[Symbol.iterator](); console.log(...petIterator); //outputs: Andy Barkley Zandro

字符串迭代器

这个[@@iterator]()方法返回迭代器,该迭代器将String价值。

const fullName = "Jin Vincent Necesario"; const fullNameIterator = fullName[Symbol.iterator](); console.log(...fullNameIterator); //outputs: J i n V i n c e n t N e c e s a r i o

集合迭代器

Set.prototype[@@iterator]()

的初始值。@@iterator的初始值相同。values财产。

const myArraySet = new Set(['mango', 'avocado', 'apple', 'apple', 'mango']); const myArraySetIterator = myArraySet[Symbol.iterator](); //to show that the initial value of the @@iterator is the same as the initial values console.log(myArraySet.values()); //output: SetIterator {"mango", "avocado", "apple"} console.log(myArraySetIterator); //output: SetIterator {"mango", "avocado", "apple"} console.log(...myArraySetIterator); //outputs: mango avocado apple

摘要

在这篇文章中,我们看到了不同JavaScript循环的优缺点。不仅如此,我们还讨论了迭代协议,它基本上有两种类型,即迭代器和可迭代协议。最后,我们已经看到内置迭代器是如何工作的。总的来说,这篇文章已经带领你解决了迭代器的难题。

西门子for循环例子_理解JavaScript中的循环缺陷和迭代协议相关推荐

  1. javascript 符号_理解JavaScript中“ =”符号的直观指南

    javascript 符号 by Kevin Kononenko 凯文·科诺年科(Kevin Kononenko) 理解JavaScript中" ="符号的直观指南 (A Visu ...

  2. C# Task 循环任务_理解C#中的ValueTask

    英文:devblogs.microsoft.com 译文:cnblogs.com/xiaoxiaotank/p/13206569.html 译者:xiaoxiaotank 前言 Task类是在.NET ...

  3. 参数 中_理解JavaScript中函数的参数

    1,arguments JavaScript的函数的参数(arguments)在函数体的内部表现为一个类似数组的对象.就是它拥有数组的方法,却不是Array的实例. 例1 我们直接打印出argumen ...

  4. 中的枚举属性函数_对于 JavaScript 中循环之间的技术差异分析

    在 JavaScript 中使用循环时,需要理解两个关键点:可枚举的属性和可迭代的对象. 可枚举的属性 可枚举对象的一个定义特征是,当通过赋值操作符向对象分配属性时,我们将内部 enumerable ...

  5. php event loop,理解javascript中的事件循环(Event Loop)

    背景 在研究js的异步的实现方式的时候,发现了JavaScript 中的 macrotask 和 microtask 的概念.在查阅了一番资料之后,对其中的执行机制有所了解,下面整理出来,希望可以帮助 ...

  6. 深入理解JavaScript中的属性和特性

    深入理解JavaScript中的属性和特性 JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaSc ...

  7. 了解JavaScript中的循环缺点和迭代协议

    目录 介绍 背景 不同的循环构成弊端 For-loop Array.forEach For-in loop For-of loop 迭代协议 迭代协议的类型 什么是迭代器协议? 什么是可迭代协议? 迭 ...

  8. 深入理解JavaScript的事件循环(Event Loop) 一、什么是事件循环

    深入理解JavaScript的事件循环(Event Loop) 一.什么是事件循环 JS的代码执行是基于一种事件循环的机制,之所以称作事件循环,MDN给出的解释为因为它经常被用于类似如下的方式来实现 ...

  9. 理解javascript中的回调函数(callback)【转】

    在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...

最新文章

  1. 【漫画】以后在有面试官问你AVL树,你就把这篇文章扔给他。
  2. 你了解机房保温棉的使用和作用吗?
  3. php如何读出xml的节点内容 两个例子
  4. 如何发送Excel中图表到邮件
  5. php中类的构造函数和析构函数,php面向对象-构造函数和析构函数详解
  6. OSI七层协议模型和各自的功能
  7. tp801单板微型计算机是什么,给TP801单板机配接RX—80打印机
  8. bzoj1096 [ZJOI2007]仓库建设(斜率)
  9. Spring MVC配置太多?试试Spring Boot
  10. 遗传算法框架deap简介与使用
  11. 通俗易懂的 Vue - Computed 原理(Watcher and Dep)
  12. Excel:把数据生成曲线图
  13. 网站被攻击了怎么办?
  14. 焦作大学计算机专业分数线,焦作大学历年分数线 2021焦作大学录取分数线
  15. python opencv合并图片
  16. 第五次课堂总结——付胤
  17. 《弗洛伊德及其后继者》读书笔记(part3)--沙利文与人际精神分析
  18. 20天学会UI设计(PS+AI)入门教程
  19. 给自己:得失心莫太重,功利心莫太强
  20. 【图像超分辨率重建】——SAN论文精读笔记

热门文章

  1. Webrtc服务器搭建转
  2. 用户名和密码都正确,无法直接登陆虚拟机上的linux
  3. 字符模式下构建、使用KVM虚拟化平台
  4. 把UltraEdit改造成VC
  5. mac os 设置汇总
  6. Linux 匿名页的反向映射
  7. (转)ATOM介绍和使用
  8. LocalDate,LocalDate,LocateDateTime的常用方法
  9. Centos 启动过程详解
  10. 计算机课玩游戏检讨500字,上电脑课玩游戏的检讨书范文