搜索
首页web前端前端问答es6中的类似于for循环有哪些

es6中的类似于for循环有哪些

Oct 17, 2022 pm 05:26 PM
javascriptes6es6数组

es6中类似于for循环有:1、“for-in”循环,其遍历的对象便不局限于数组,还可以遍历对象,语法“for(键名 in 对象) {...}”;2、forEach循环,为数组中含有有效值的每一项执行一次callback函数,语法“array.forEach(callback函数,thisValue)”;3、“for-of”循环,语法“for(当前值 of 数组){...}”。

es6中的类似于for循环有哪些

本教程操作环境:windows7系统、ECMAScript 6版、Dell G3电脑。

ECMAScript6(简称 ES6)中支持 4 种 for 循环。

  • 简单for循环

  • for-in

  • forEach

  • for-of

下面我们就来看看这 4 种 for 循环。

简单 for 循环

下面先来看看大家最常见的一种写法:

const arr = [1, 2, 3];
for(let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

1.png

当数组长度在循环过程中不会改变时,我们应将数组长度用变量存储起来,这样会获得更好的效率,下面是改进的写法:

const arr = [1, 2, 3];
for(let i = 0, len = arr.length; i < len; i++) {
    console.log(arr[i]);
}

1-2.png

for-in

通常情况下,我们可以用 for-in 来遍历一遍数组的内容,代码如下:

const arr = [1, 2, 3];
let index;
for(index in arr) {
    console.log("arr[" + index + "] = " + arr[index]);
}

一般情况下,运行结果如下:

2.png

但这么做往往会出现问题。

for-in 的真相

for-in 循环遍历的是对象的属性,而不是数组的索引。因此, for-in 遍历的对象便不局限于数组,还可以遍历对象。例子如下:

const person = {
    fname: "san",
    lname: "zhang",
    age: 99
};
let info;
for(info in person) {
    console.log("person[" + info + "] = " + person[info]);
}

结果如下:

2-2.png

需要注意的是, for-in 遍历属性的顺序并不确定,即输出的结果顺序与属性在对象中的顺序无关,也与属性的字母顺序无关,与其他任何顺序也无关。

Array 的真相

Array 在 Javascript 中是一个对象, Array 的索引是属性名。事实上, Javascript 中的 “array” 有些误导性, Javascript 中的 Array 并不像大部分其他语言的数组。首先, Javascript 中的 Array 在内存上并不连续,其次, Array 的索引并不是指偏移量。实际上, Array 的索引也不是 Number 类型,而是 String 类型的。我们可以正确使用如 arr[0] 的写法的原因是语言可以自动将 Number 类型的 0 转换成 String 类型的 “0″ 。所以,在 Javascript 中从来就没有 Array 的索引,而只有类似 “0″ 、 “1″ 等等的属性。有趣的是,每个 Array 对象都有一个 length 的属性,导致其表现地更像其他语言的数组。但为什么在遍历 Array 对象的时候没有输出 length 这一条属性呢?那是因为 for-in 只能遍历“可枚举的属性”, length 属于不可枚举属性,实际上, Array 对象还有许多其他不可枚举的属性。

现在,我们再回过头来看看用 for-in 来循环数组的例子,我们修改一下前面遍历数组的例子:

const arr = [1, 2, 3];
arr.name = "Hello world";
let index;
for(index in arr) {
    console.log("arr[" + index + "] = " + arr[index]);
}

运行结果是:

2-3.png

我们看到 for-in 循环访问了我们新增的 “name” 属性,因为 for-in 遍历了对象的所有属性,而不仅仅是“索引”。同时需要注意的是,此处输出的索引值,即 “0″、 “1″、 “2″不是 Number 类型的,而是 String 类型的,因为其就是作为属性输出,而不是索引。那是不是说不在我们的 Array 对象中添加新的属性,我们就可以只输出数组中的内容了呢?答案是否定的。因为 for-in 不仅仅遍历 array 自身的属性,其还遍历 array 原型链上的所有可枚举的属性。下面我们看个例子:

Array.prototype.fatherName = "Father";
const arr = [1, 2, 3];
arr.name = "Hello world";
let index;
for(index in arr) {
    console.log("arr[" + index + "] = " + arr[index]);
}

运行结果是:

arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[name] = Hello world
arr[fatherName] = Father

写到这里,我们可以发现 for-in 并不适合用来遍历 Array 中的元素,其更适合遍历对象中的属性,这也是其被创造出来的初衷。却有一种情况例外,就是稀疏数组。考虑下面的例子:

let key;
const arr = [];
arr[0] = "a";
arr[100] = "b";
arr[10000] = "c";
for(key in arr) {
    if(arr.hasOwnProperty(key)  &&   
        /^0$|^[1-9]\d*$/.test(key) &&   
        key <= 4294967294              
        ) {
        console.log(arr[key]);
    }
}

for-in 只会遍历存在的实体,上面的例子中, for-in 遍历了3次(遍历属性分别为”0″、 “100″、 “10000″的元素,普通 for 循环则会遍历 10001 次)。所以,只要处理得当, for-in 在遍历 Array 中元素也能发挥巨大作用。

为了避免重复劳动,我们可以包装一下上面的代码:

function arrayHasOwnIndex(array, prop) {
    return array.hasOwnProperty(prop) &&
        /^0$|^[1-9]\d*$/.test(prop) &&
        prop <= 4294967294; // 2^32 - 2
}

使用示例如下:

for (let key in arr) {
    if (arrayHasOwnIndex(arr, key)) {
        console.log(arr[key]);
    }
}

for-in 性能

正如上面所说,每次迭代操作会同时搜索实例或者原型属性, for-in 循环的每次迭代都会产生更多开销,因此要比其他循环类型慢,一般速度为其他类型循环的 1/7。因此,除非明确需要迭代一个属性数量未知的对象,否则应避免使用 for-in 循环。如果需要遍历一个数量有限的已知属性列表,使用其他循环会更快,比如下面的例子:

const obj = {
    "prop1": "value1",
    "prop2": "value2"
};
 
const props = ["prop1", "prop2"];
for(let i = 0; i < props.length; i++) {
    console.log(obj[props[i]]);
}

上面代码中,将对象的属性都存入一个数组中,相对于 for-in 查找每一个属性,该代码只关注给定的属性,节省了循环的开销和时间。

forEach

在 ES5 中,引入了新的循环,即 forEach 循环。

const arr = [1, 2, 3];
arr.forEach((data) => {
    console.log(data);
});

运行结果:

1
2
3

forEach 方法为数组中含有有效值的每一项执行一次 callback 函数,那些已删除(使用 delete 方法等情况)或者从未赋值的项将被跳过(不包括那些值为 undefined 或 null 的项)。 callback 函数会被依次传入三个参数:

  • 数组当前项的值;
  • 数组当前项的索引;
  • 数组对象本身;

需要注意的是,forEach 遍历的范围在第一次调用 callback 前就会确定。调用forEach 后添加到数组中的项不会被 callback 访问到。如果已经存在的值被改变,则传递给 callback 的值是 forEach 遍历到他们那一刻的值。已删除的项不会被遍历到。

const arr = [];
arr[0] = "a";
arr[3] = "b";
arr[10] = "c";
arr.name = "Hello world";
arr.forEach((data, index, array) => {
    console.log(data, index, array);
});

运行结果:

a 0 ["a", 3: "b", 10: "c", name: "Hello world"]
b 3 ["a", 3: "b", 10: "c", name: "Hello world"]
c 10 ["a", 3: "b", 10: "c", name: "Hello world"]

这里的 index 是 Number 类型,并且也不会像 for-in 一样遍历原型链上的属性。

所以,使用 forEach 时,我们不需要专门地声明 index 和遍历的元素,因为这些都作为回调函数的参数。

另外,forEach 将会遍历数组中的所有元素,但是 ES5 定义了一些其他有用的方法,下面是一部分:

  • every: 循环在第一次 return false 后返回
  • some: 循环在第一次 return true 后返回
  • filter: 返回一个新的数组,该数组内的元素满足回调函数
  • map: 将原数组中的元素处理后再返回
  • reduce: 对数组中的元素依次处理,将上次处理结果作为下次处理的输入,最后得到最终结果。

forEach 性能

大家可以看 jsPerf ,在不同浏览器下测试的结果都是 forEach 的速度不如 for。如果大家把测试代码放在控制台的话,可能会得到不一样的结果,主要原因是控制台的执行环境与真实的代码执行环境有所区别。

for-of

先来看个例子:

const arr = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;];
for(let data of arr) {
    console.log(data);
}

运行结果是:

a
b
c

为什么要引进 for-of?

要回答这个问题,我们先来看看ES6之前的 3 种 for 循环有什么缺陷:

  • forEach 不能 break 和 return;
  • for-in 缺点更加明显,它不仅遍历数组中的元素,还会遍历自定义的属性,甚至原型链上的属性都被访问到。而且,遍历数组元素的顺序可能是随机的。

所以,鉴于以上种种缺陷,我们需要改进原先的 for 循环。但 ES6 不会破坏你已经写好的 JS 代码。目前,成千上万的 Web 网站依赖 for-in 循环,其中一些网站甚至将其用于数组遍历。如果想通过修正 for-in 循环增加数组遍历支持会让这一切变得更加混乱,因此,标准委员会在 ES6 中增加了一种新的循环语法来解决目前的问题,即 for-of 。

那 for-of 到底可以干什么呢?

  • 跟 forEach 相比,可以正确响应 break, continue, return。
  • for-of 循环不仅支持数组,还支持大多数类数组对象,例如 DOM nodelist 对象。
  • for-of 循环也支持字符串遍历,它将字符串视为一系列 Unicode 字符来进行遍历。
  • for-of 也支持 Map 和 Set (两者均为 ES6 中新增的类型)对象遍历。

总结一下,for-of 循环有以下几个特征:

  • 这是最简洁、最直接的遍历数组元素的语法。
  • 这个方法避开了 for-in 循环的所有缺陷。
  • 与 forEach 不同的是,它可以正确响应 break、continue 和 return 语句。
  • 其不仅可以遍历数组,还可以遍历类数组对象和其他可迭代对象。

但需要注意的是,for-of循环不支持普通对象,但如果你想迭代一个对象的属性,你可以用
for-in 循环(这也是它的本职工作)。

最后要说的是,ES6 引进的另一个方式也能实现遍历数组的值,那就是 Iterator。上个例子:

const arr = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;];
const iter = arr[Symbol.iterator]();
 
iter.next() // { value: &#39;a&#39;, done: false }
iter.next() // { value: &#39;b&#39;, done: false }
iter.next() // { value: &#39;c&#39;, done: false }
iter.next() // { value: undefined, done: true }

前面的不多说,重点描述for-of

for-of循环不仅支持数组,还支持大多数类数组对象,例如DOM NodeList对象

for-of循环也支持字符串遍历,它将字符串视为一系列的Unicode字符来进行遍历:

window.onload=function(){ 
   const arr = [55,00, 11, 22];
   arr.name = "hello";
  // Array.prototype.FatherName = &#39;FatherName&#39;;
   /*for(let key in arr){
    console.log(&#39;key=&#39;+key+&#39;,key.value=&#39;+arr[key]);
   }*/
   /* arr.forEach((data) => {console.log(data);});*/
  /* arr.forEach((data,index,arr) => {console.log(data+&#39;,&#39;+index+&#39;,&#39;+arr);});*/
  /*for(let key of arr){
    console.log(key);
  }*/
  var string1 = &#39;abcdefghijklmn&#39;;
  var string2 = &#39;opqrstuvwxyc&#39;;
  const stringArr = [string1,string2];
  for(let key of stringArr){
    console.log(key);
  }
  for(let key of string1){
    console.log(key);
  }
}

结果:

0.png

现在,只需记住:

  • 这是最简洁、最直接的遍历数组元素的语法
  • 这个方法避开了for-in循环的所有缺陷
  • 与forEach()不同的是,它可以正确响应break、continue和return语句

for-in循环用来遍历对象属性。

for-of循环用来遍历数据—例如数组中的值。

它同样支持Map和Set对象遍历。

Map和Set对象是ES6中新增的类型。ES6中的Map和Set和java中并无太大出入。

SetMap类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key。

要创建一个Set,需要提供一个Array作为输入,或者直接创建一个空Set

var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3

1.png

重复元素在Set中自动被过滤:

var s = new Set([1, 2, 3, 3, '3']);
console.log(s); // Set {1, 2, 3, "3"}

2.png

通过add(key)方法可以添加元素到Set中,可以重复添加,但不会有效果:

var s = new Set([1, 2, 3]);
s.add(4);
s; // Set {1, 2, 3, 4}
s.add(4);
s; // Set {1, 2, 3, 4}

通过delete(key)方法可以删除元素:

var s = new Set([1, 2, 3]);
s; // Set {1, 2, 3}
s.delete(3);
s; // Set {1, 2}

Set对象可以自动排除重复项

var string1 = &#39;abcdefghijklmn&#39;;
  var string2 = &#39;opqrstuvwxyc&#39;;
  var string3 = &#39;opqrstuvwxyc&#39;;
  var string4 = &#39;opqrstuvwxyz&#39;;
 
  const stringArr = [string1,string2,string3,string4];
 
 
 var newSet = new Set(stringArr);
  for(let key of newSet){
    console.log(key);
  }

结果:

3.png

Map对象稍有不同:内含的数据由键值对组成,所以你需要使用解构(destructuring)来将键值对拆解为两个独立的变量:

for (var [key, value] of phoneBookMap) {   
console.log(key + "&#39;s phone number is: " + value);
}

 示例

var m = new Map([[1, &#39;Michael&#39;], [2, &#39;Bob&#39;], [3, &#39;Tracy&#39;]]);
  var map = new Map([[&#39;1&#39;,&#39;Jckey&#39;],[&#39;2&#39;,&#39;Mike&#39;],[&#39;3&#39;,&#39;zhengxin&#39;]]);
  map.set(&#39;4&#39;,&#39;Adam&#39;);//添加key-value
  map.set(&#39;5&#39;,&#39;Tom&#39;);
  map.set(&#39;6&#39;,&#39;Jerry&#39;);
  console.log(map.get(&#39;6&#39;));
  map.delete(&#39;6&#39;);
   console.log(map.get(&#39;6&#39;));
  for(var [key,value] of map) {
    console.log(&#39;key=&#39;+key+&#39; , value=&#39;+value);
  }

结果:

4.png

【相关推荐:javascript视频教程编程视频

以上是es6中的类似于for循环有哪些的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
HTML和React:标记与组件之间的关系HTML和React:标记与组件之间的关系Apr 12, 2025 am 12:03 AM

HTML和React的关系是前端开发的核心,它们共同构建现代Web应用的用户界面。1)HTML定义内容结构和语义,React通过组件化构建动态界面。2)React组件使用JSX语法嵌入HTML,实现智能渲染。3)组件生命周期管理HTML渲染,根据状态和属性动态更新。4)使用组件优化HTML结构,提高可维护性。5)性能优化包括避免不必要渲染,使用key属性,保持组件单一职责。

反应与前端:建立互动体验反应与前端:建立互动体验Apr 11, 2025 am 12:02 AM

React是构建交互式前端体验的首选工具。1)React通过组件化和虚拟DOM简化UI开发。2)组件分为函数组件和类组件,函数组件更简洁,类组件提供更多生命周期方法。3)React的工作原理依赖虚拟DOM和调和算法,提高性能。4)状态管理使用useState或this.state,生命周期方法如componentDidMount用于特定逻辑。5)基本用法包括创建组件和管理状态,高级用法涉及自定义钩子和性能优化。6)常见错误包括状态更新不当和性能问题,调试技巧包括使用ReactDevTools和优

React和前端堆栈:工具和技术React和前端堆栈:工具和技术Apr 10, 2025 am 09:34 AM

React是一个用于构建用户界面的JavaScript库,其核心是组件化和状态管理。1)通过组件化和状态管理简化UI开发。2)工作原理包括调和和渲染,优化可通过React.memo和useMemo实现。3)基本用法是创建并渲染组件,高级用法包括使用Hooks和ContextAPI。4)常见错误如状态更新不当,可使用ReactDevTools调试。5)性能优化包括使用React.memo、虚拟化列表和CodeSplitting,保持代码可读性和可维护性是最佳实践。

React在HTML中的作用:增强用户体验React在HTML中的作用:增强用户体验Apr 09, 2025 am 12:11 AM

React通过JSX与HTML结合,提升用户体验。1)JSX嵌入HTML,使开发更直观。2)虚拟DOM机制优化性能,减少DOM操作。3)组件化管理UI,提高可维护性。4)状态管理和事件处理增强交互性。

REACT组件:在HTML中创建可重复使用的元素REACT组件:在HTML中创建可重复使用的元素Apr 08, 2025 pm 05:53 PM

React组件可以通过函数或类定义,封装UI逻辑并通过props接受输入数据。1)定义组件:使用函数或类,返回React元素。2)渲染组件:React调用render方法或执行函数组件。3)复用组件:通过props传递数据,构建复杂UI。组件的生命周期方法允许在不同阶段执行逻辑,提升开发效率和代码可维护性。

反应严格模式目的反应严格模式目的Apr 02, 2025 pm 05:51 PM

React严格模式是一种开发工具,可通过激活其他检查和警告来突出反应应用中的潜在问题。它有助于识别遗产代码,不安全的生命周期和副作用,鼓励现代反应实践。

反应碎片使用反应碎片使用Apr 02, 2025 pm 05:50 PM

React片段允许将儿童分组而没有额外的DOM节点,增强结构,性能和可访问性。他们支持钥匙以进行有效的列表渲染。

反应和解过程反应和解过程Apr 02, 2025 pm 05:49 PM

本文讨论了React的对帐过程,详细介绍了它如何有效地更新DOM。关键步骤包括触发对帐,创建虚拟DOM,使用扩散算法以及应用最小的DOM更新。它还覆盖了经家

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。