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

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

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

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

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

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

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

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

 let userList = [ 'ghostwu', '悟空', '八戒' ];
let iterator = userList[Symbol.iterator]();
console.log( iterator.next() ); //{ value : 'ghostwu', done : false }
console.log( iterator.next() ); //{ value : '悟空', done : false }
console.log( iterator.next() ); //{ value : '八戒', done : false }
console.log( iterator.next() ); //{ value : undefined, done : false }

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

 function isIterable( obj ){
return typeof obj[Symbol.iterator] === 'function';
}
console.log( isIterable( [ 10, 20 ,30 ] ) ); //true
console.log( isIterable( "ghostwu" ) ); //true
console.log( isIterable( new Map() ) ); //true
console.log( isIterable( new Set() ) ); //true
console.log( isIterable( new Object() ) ); //false
console.log( isIterable( {} ) );//false

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

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

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

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

 let obj = {
items : [],
*[Symbol.iterator](){
for( let item of this.items ) {
yield item;
}
}
}
obj.items.push( 10 );
obj.items.push( 20 );
obj.items.push( 30 );
var iterator = obj[Symbol.iterator]();
console.log( iterator.next() ); //{ value : 10, done: false }
console.log( iterator.next() ); //{ value : 20, done : false }
console.log( iterator.next() ); //{ value : 30, done : false }
console.log( iterator.next() ); //{ value : undefined, done : true }

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

 let obj = {
items : [],
*[Symbol.iterator](){
for( let item of this.items ) {
yield item;
}
}
}
obj.items.push( 10 );
obj.items.push( 20 );
obj.items.push( 30 ); for ( let val of obj ) {
console.log( val );
}

内置迭代器:

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

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

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

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

 let userList = [ 'ghostwu', '悟空', '八戒' ];

 for ( let name of userList.entries() ) {
console.log( name );
} let set = new Set( [ 10, 20, 30 ] );
for ( let num of set.entries() ){
console.log( num );
} let map = new Map( [ [ 'name', 'ghostwu' ], [ 'age', 22 ] ] );
for ( let detail of map.entries() ){
console.log( detail );
}

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

 let set = new Set( [ 10, 20, 30 ] );
for ( let num of set.values() ){
console.log( num );
} let map = new Map( [ [ 'name', 'ghostwu' ], [ 'age', 22 ] ] );
for ( let detail of map.values() ){
console.log( detail );
}

 let set = new Set( [ 10, 20, 30 ] );
for ( let num of set.keys() ){
console.log( num );
} let map = new Map( [ [ 'name', 'ghostwu' ], [ 'age', 22 ] ] );
for ( let detail of map.keys() ){
console.log( detail );
}

 默认的迭代器:

 let userList = [ 'ghostwu', '悟空', '八戒' ];

 //相当于调用values
for ( let name of userList ) {
console.log( name );
} let set = new Set( [ 10, 20, 30 ] );
//相当于调用values
for ( let num of set ){
console.log( num );
} let map = new Map( [ [ 'name', 'ghostwu' ], [ 'age', 22 ] ] );
//相当于调用entries
for ( let detail of map ){
console.log( detail );
}

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

 let map = new Map( [ [ 'name', 'ghostwu' ], [ 'age', 22 ] ] );
for ( let [ key, value ] of map ) {
console.log( key + '--->' + value );
}

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

 let set = new Set( [ 10, 20, 30 ] );
let arr = [...set];
console.log( arr ); // [10,20,30] let map = new Map( [ [ 'name', 'ghostwu' ], [ 'age', 22 ] ]);
console.log( [...map] ); // [ [ 'name', 'ghostwu' ], [ 'age', 22 ] ] let arr1 = [ 10, 20, 30 ];
let arr2 = [ 'ghostwu', '八戒', '悟空' ];
let combine = [ ...arr1, ...arr2, 'done' ];
console.log( combine ); // [10, 20, 30, "ghostwu", "八戒", "悟空", "done"]

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

  1. [js高手之路] es6系列教程 - 迭代器与生成器详解

    什么是迭代器? 迭代器是一种特殊对象,这种对象具有以下特点: 1,所有对象都有一个next方法 2,每次调用next方法,都会返回一个对象,该对象包含两个属性,一个是value, 表示下一个将要返回的 ...

  2. [js高手之路] es6系列教程 - 对象功能扩展详解

    第一:字面量对象的方法,支持缩写形式 //es6之前,这么写 var User = { name : 'ghostwu', showName : function(){ return this.nam ...

  3. [js高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race)

    关于promise我在之前的文章已经应用过好几次,如[js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist,本文就来讲解下pro ...

  4. [js高手之路] es6系列教程 - 函数的默认参数详解

    在ES6之前,我们一般用短路表达式处理默认参数 function show( a, b ){ var a = a || 10; var b = b || 20; console.log( a, b ) ...

  5. [js高手之路] es6系列教程 - 箭头函数详解

    箭头函数是es6新增的非常有意思的特性,初次写起来,可能会觉得别扭,习惯之后,会发现很精简. 什么是箭头函数? 箭头函数是一种使用箭头( => )定义函数的新语法, 主要有以下特性: 不能通过n ...

  6. [js高手之路] es6系列教程 - var, let, const详解

    function show( flag ){ console.log( a ); if( flag ){ var a = 'ghostwu'; return a; } else { console.l ...

  7. [js高手之路] es6系列教程 - 不定参数与展开运算符(...)

    三个点(...)在es6中,有两个含义: 用在形参中, 表示传递给他的参数集合, 类似于arguments, 叫不定参数. 语法格式:  在形参面前加三个点( ... ) 用在数组前面,可以把数组的值 ...

  8. [js高手之路]es6系列教程 - 解构详解

    解构通俗点说,就是通过一种特定格式,快捷的读取对象/数组中的数据的方法, es6之前,我们通过对象名称[键] 读取数据 var User = { 'name' : 'ghostwu', 'age' : ...

  9. [js高手之路] es6系列教程 - Set详解与抽奖程序应用实战

    我们还是从一些现有的需求和问题出发,为什么会有set,他的存在是为了解决什么问题? 我们看一个这样的例子,为一个对象添加键值对 var obj = Object.create( null ); obj ...

随机推荐

  1. JSON数据解析及gson.jar包

    从服务器端接收数据的时候,那些数据必须以浏览器能够理解的格式来发送. 服务器端的编程语言只能以如下 3 种格式返回数据: HTML XML JSON JSON一种简单的数据格式,比xml更轻巧. JS ...

  2. java 的equals 与== ,null与isempty的区别

    1 . == 是为了判断等号两边 变量 所对应 的 内存中的 值  是否  相等, 只是 值 的比较. 2. 假如    String s1 = new String("abc") ...

  3. 【NOI2010】海拔【平面图最小割】

    [问题描写叙述] YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见.能够将YT市看作 一个正方形,每个区域也可看作一个正方形.从而.YT城市中包含(n+1)×(n+ ...

  4. TCP服务端开发为例--web开发不同url请求走不同control方法

    拿java的web开发为例子,相信有很多小伙伴是做j2EE开发的,htpp请求,json数据传输都是工作中经常用的,查询请求,添加请求,修改请求前端配个url,例如https://localhost/ ...

  5. CI环境配置

    CI:php的MVC框架M(模型model):与数据库打交道的,一般情况下数据库里面的一张表对应一个Model,在里面对应该表的增删改查的操作V(视图view):用户看到的界面,其中很多数据是从数据库 ...

  6. Iframe简单介绍(一)

    Iframe可以用在以下几个场景 1.典型系统结构,左侧是功能树,右侧就是一些常见table或者表单之类的.为了每一个功能,单独分离出来,采用iframe. 2.AJAX上传文件 3.加载别的网站内容 ...

  7. SSH之免密登陆

    又来了,上头让小轩我在服务器中写一个Shell脚本,主要用来在机器B中定时备份机器A中的一些文件.那么,小轩是怎么想的呢? 在小轩的知识库里,现在有scp和ssh两个玩具.别的还真没有其他什么东西了. ...

  8. 这么说吧,java线程池的实现原理其实很简单

    好处 : 线程是稀缺资源,如果被无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池对线程进行统一分配.调优和监控,有以下好处: 1.降低资源消耗: 2.提高响应速度: 3.提高线 ...

  9. 1. 生成三行文本,过滤文本,cp不覆盖,find查找文件,sed打印行,查看系统信息,磁盘分区

  10. ios 去掉字符串中的空格 和指定的字符

    [问题分析] .使用NSString中的stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]方法只是去掉左右 ...