分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

[js高手之路] es6系列教程 - 迭代器,生成器,for...of,entries,values,keys等详解

发布时间:2023-09-06 01:13责任编辑:蔡小小关键词:jses6

接着上文[js高手之路] es6系列教程 - 迭代器与生成器详解继续. 

在es6中引入了一个新的循环结构for ....of, 主要是用来循环可迭代的对象,那么什么是可迭代的对象呢?

可迭代的对象一般都有Symbol.iterator属性,你可以在控制台中用console.dir打印数组,Map,Set,在他们的原型对象(prototype)上面就能找到。这个属性与迭代器密切相关,通过该函数可以返回一个迭代器,下文,我会举一个例子。一般来说所有的集合对象(数组,Set,Map 以及字符串)都是可迭代的对象。这些对象中都有默认的迭代器.

for..of循环的遍历原理:

循环每执行一次都会调用可迭代对象的next()方法, 并将迭代器返回的结果对象的value属性存储在一个变量中,循环将持续执行这一过程,直到done返回true

1 let values = [ 10, 20, 30 ];2 for( let val of values ) {3 ????console.log( val );4 }

这段for...of循环的代码通过调用values数组的Symbol.iterator方法来获取迭代器, 这一步是由js引擎自动完成的,随后迭代器的next()方法被多次调用,返回对象的value值并存储在变量val中,依次为: 10, 20, 30,done为true的时候退出,最后 不会把undefined赋值给val.

利用Symbol.iterator访问默认的迭代器

1 let userList = [ ‘ghostwu‘, ‘悟空‘, ‘八戒‘ ];2 let iterator = userList[Symbol.iterator]();3 console.log( iterator.next() ); //{ value : ‘ghostwu‘, done : false }4 console.log( iterator.next() ); //{ value : ‘悟空‘, done : false }5 console.log( iterator.next() ); //{ value : ‘八戒‘, done : false }6 console.log( iterator.next() ); //{ value : undefined, done : false }

由于具有Symbol.iterator属性的对象都有默认的迭代器,这个特性可以用来检测对象是否为可迭代对象.

1 function isIterable( obj ){2 ????return typeof obj[Symbol.iterator] === ‘function‘;3 }4 console.log( isIterable( [ 10, 20 ,30 ] ) ); //true5 console.log( isIterable( "ghostwu" ) ); //true6 console.log( isIterable( new Map() ) ); //true7 console.log( isIterable( new Set() ) ); //true8 console.log( isIterable( new Object() ) ); //false9 console.log( isIterable( {} ) );//false

所以,for..of不能遍历对象( json )

var obj = { ???name : ‘ghostwu‘, ???age : 22, ???sex : ‘man‘};for( var val of obj ) { ???console.log( val );}

上面这种遍历方式,就会报错.

但是,我们可以为对象增加一个迭代器方法

 1 let obj = { 2 ????items : [], 3 ????*[Symbol.iterator](){ 4 ????????for( let item of this.items ) { 5 ????????????yield item; 6 ????????} 7 ????} 8 } 9 obj.items.push( 10 );10 obj.items.push( 20 );11 obj.items.push( 30 );12 var iterator = obj[Symbol.iterator]();13 console.log( iterator.next() ); //{ value : 10, done: false }14 console.log( iterator.next() ); //{ value : 20, done : false }15 console.log( iterator.next() ); //{ value : 30, done : false }16 console.log( iterator.next() ); //{ value : undefined, done : true }

给Symbol.iterator属性添加一个生成器,那么对象就具备迭代器的功能了,那么就能够使用for...of方法了

 1 let obj = { 2 ????items : [], 3 ????*[Symbol.iterator](){ 4 ????????for( let item of this.items ) { 5 ????????????yield item; 6 ????????} 7 ????} 8 } 9 obj.items.push( 10 );10 obj.items.push( 20 );11 obj.items.push( 30 );12 13 for ( let val of obj ) {14 ????console.log( val );15 }

内置迭代器:

可迭代的对象,都内置以下3种迭代器

entries(): 返回一个迭代器,值为键值对

values(): 返回一个迭代器, 值为集合的值

keys(): 返回一个迭代器,值为集合中的所有键

 1 let userList = [ ‘ghostwu‘, ‘悟空‘, ‘八戒‘ ]; 2 ?3 for ( let name of userList.entries() ) { 4 ????console.log( name ); 5 } 6 ?7 let set = new Set( [ 10, 20, 30 ] ); 8 for ( let num of set.entries() ){ 9 ????console.log( num );10 }11 12 let map = new Map( [ [ ‘name‘, ‘ghostwu‘ ], [ ‘age‘, 22 ] ] );13 for ( let detail of map.entries() ){14 ????console.log( detail );15 }

entries返回的是键值对,注意Set集合,返回的键和值是一样的.

1 let set = new Set( [ 10, 20, 30 ] );2 for ( let num of set.values() ){3 ????console.log( num );4 }5 6 let map = new Map( [ [ ‘name‘, ‘ghostwu‘ ], [ ‘age‘, 22 ] ] );7 for ( let detail of map.values() ){8 ????console.log( detail );9 }
1 let set = new Set( [ 10, 20, 30 ] );2 for ( let num of set.keys() ){3 ????console.log( num );4 }5 6 let map = new Map( [ [ ‘name‘, ‘ghostwu‘ ], [ ‘age‘, 22 ] ] );7 for ( let detail of map.keys() ){8 ????console.log( detail );9 }

 默认的迭代器:

 1 let userList = [ ‘ghostwu‘, ‘悟空‘, ‘八戒‘ ]; 2 ?3 //相当于调用values 4 for ( let name of userList ) { 5 ????console.log( name ); 6 } 7 ?8 let set = new Set( [ 10, 20, 30 ] ); 9 //相当于调用values10 for ( let num of set ){11 ????console.log( num );12 }13 14 let map = new Map( [ [ ‘name‘, ‘ghostwu‘ ], [ ‘age‘, 22 ] ] );15 //相当于调用entries16 for ( let detail of map ){17 ????console.log( detail );18 }

Map的默认行为,可以用解构来简写:

1 let map = new Map( [ [ ‘name‘, ‘ghostwu‘ ], [ ‘age‘, 22 ] ] );2 for ( let [ key, value ] of map ) {3 ????console.log( key ?+ ‘--->‘ + value );4 }

利用展开运算符把Set与Map转化成数组

 1 let set = new Set( [ 10, 20, 30 ] ); 2 let arr = [...set]; 3 console.log( arr ); // [10,20,30] 4 ?5 let map = new Map( [ [ ‘name‘, ‘ghostwu‘ ], [ ‘age‘, 22 ] ]); 6 console.log( [...map] ); // [ [ ‘name‘, ‘ghostwu‘ ], [ ‘age‘, 22 ] ] 7 ?8 let arr1 = [ 10, 20, 30 ]; 9 let arr2 = [ ‘ghostwu‘, ‘八戒‘, ‘悟空‘ ];10 let combine = [ ...arr1, ...arr2, ‘done‘ ];11 console.log( combine ); // [10, 20, 30, "ghostwu", "八戒", "悟空", "done"]

[js高手之路] es6系列教程 - 迭代器,生成器,for...of,entries,values,keys等详解

原文地址:http://www.cnblogs.com/ghostwu/p/7587498.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved