JS中循环、递归、迭代、遍历、枚举的概念辨析
发布网友
发布时间:2024-10-13 14:53
我来回答
共1个回答
热心网友
时间:2024-10-25 23:48
循环是程序设计语言中反复执行某些代码的一种计算机处理过程
以上是百科中对循环的解释,其含义也很简单。重复执行一段代码就是循环。
其实这就是第一种理解,即循环是一种抽象的概念,或者说是代码的一种执行方式。
在编程当中提到循环就自然联想的循环语句,循环语句由循环体和循环终止条件两部分组成。重复执行的语句就是循环体,而决定循环是否继续下去的就是循环终止条件。
在JS当中就有for、while、do-while等循环语句
上面是JS中的一个while循环,其中index < 4就是循环终止条件,而大括号中的内容就是循环体。
在JS当中,循环广义上理解就是一种“重复执行代码”这种行为。狭义的理解就是while等循环语句。
递归在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。
递归的基本思想就是把规模大的问题转化为规模小的相似的子问题来解决。递归递归,自然就分为“递”和“归”两部分,“递”是指“递去”,即将大问题不断分解为相似的小问题的过程;“归”是指“归来”,即当无法再继续分解时,回收所有小问题的结果,最终解决一开始的大问题。
递归有所谓的三大要素:
对应上面的例子,函数功能就是“钥匙”;终止条件就是“没有门的屋子”;重复的子问题就是“开门”。
递归似乎就是循环,递归函数是循环体;递归终止条件是循环终止条件。
因此我总结,递归属于循环,它是一种通过函数自调用实现的特殊循环。
迭代的概念就比较复杂了,其在不同的领域有着不同的概念。
所以在JS当中,可以理解为迭代就是循环。
迭代器就是实现迭代的一种工具,它是一种跨类型的迭代方法。
在JS当中有迭代器的概念,按照我的理解,迭代器就是实现迭代的一种工具,它是一种跨类型的迭代方法。
在上面这个例子中for-of正是调用了items的迭代器,实现了迭代。
首先我先从汉语词语的角度看一看“遍历”,例如古文当中有这样一种用法:“乃以是履弃之于道旁,即遍历人家捕之,若有女履者,捕之以告。”这里的遍是全面、到处的意思;而历,在这里应当作逐一、逐个地的来讲。所以这里的遍历的意思是全部逐一的。
进而引申到编程当中,比如“遍历数组”,其含义就应当是:“全部逐一的访问数组中的每个元素”。
当然根据我所查到的资料,遍历这个概念主要还是应用于树/图这种数据结构,指按照某种顺序依次访问树/图中的所有节点。只不过遍历这个概念同样适用于数组等多元素集合。当然在JS当中是鲜少涉及树/图的主要还是遍历数组等集合。
过去我是认为JS中的遍历与循环是同一个意思的,但是常常又觉得这两个概念是有一定的区别的,只是区别是什么我说不上来。
不过现在我尝试谈一谈它们的区别。
上面是一个数组以及其关联的迭代器对象,那么对于它来说下面的操作是不是循环?是,这里都使用了while这个循环语句了;但是不是遍历?我认为不是,因为并没有访问数组中的每个元素。
下面这个操作,是不是循环?是;是不是遍历?也是,因为访问了数组中所有的元素
所以我的结论是:遍历属于循环,或者说循环是实现遍历的一种方式。而且遍历一定是要和某个数据相绑定的,如遍历树、遍历图、遍历数组。而循环则不需要。
在编程当中的枚举作为名词和动词是两种不同的含义。
当枚举作为名词的时候,指的是枚举类,当然JS当中是没有枚举类的语法的,下面展示一下TS中的枚举类。
一个熟悉的屏幕空间事件类型:
当然我们在JS中也可以模拟出枚举类的效果,比如写一个枚举函数:
也可以模拟一个枚举类:
枚举作为动词其概念其实就是“枚举法”即把所有的可能情况都列举出来。具体到JS当中枚举则是主要是指对象的一个操作,因为对象的属性有一个[[Enumerable]]特性,即属性否可枚举,并且对象有与可枚举性相关的一些方法,如keys()、values()。
但是当写到这里的时候,我逐渐迷茫,因为我发现JS对象属性的可枚举性决定了它能否被for-of遍历,那么这里的枚举岂非就是遍历?
或许这就是答案