es6的for of可以遍历对象吗
es6的“for of”不能遍历对象。原因:ES6中引入了Iterator接口,只有提供了Iterator接口的数据类型才可以使用“for-of”来循环遍历;而普通对象默认没有提供Iterator接口,因此无法用“for-of”来进行遍历。
本教程操作环境:windows7系统、ECMAScript 6版、Dell G3电脑。
随着前端的不断发展,光循环就出现了好多种方法,for、forEach、do..while、for...in等等,不过这些循环也都各有各的应用场景和优缺点。
ES6又为我们提供了新的循环方法for...of,它可以循环字符串、数组及其他类数组对象,那作为最普遍存在的Object对象,按理,可以循环?
我们看一下下方的代码示例:
{ // 迭代数组 const iterable = ['a', 'b']; for (const value of iterable) { console.log(value); } // output: a b } { // 普通对象 const obj = { a: 'A', b: 'B' } for(const item of obj){ console.log(item) } // Uncaught TypeError: obj is not iterable }
oh no,报错了:Uncaught TypeError: obj is not iterable
。提示obj是不可迭代的,显然直接用for...of
去遍历Object对象是不行的。
那么可以遍历大部分数据结构的for...of为何不能遍历Object对象?
原因:
ES6 中引入了 Iterator,只有提供了 Iterator 接口的数据类型才可以使用 for-of 来循环遍历,而 Array、Set、Map、某些类数组如 arguments 等数据类型都默认提供了 Iterator 接口,所以它们可以使用 for-of 来进行遍历。
而对于普通的对象,for...of结构不能直接使用,会报错,提示obj is not iterable
,也就是说普通对象默认没有Iterator接口,必须部署了 Iterator 接口后才能使用。
怎么解决?让for-of 遍历对象
那么原因清楚了,该怎么解决呢?能不能为对象已经其它的一些数据类型提供 Iterator 接口呢
答案是可以的,ES6 同时提供了 Symbol.iterator 属性,只要一个数据结构有这个属性,就会被视为有 Iterator 接口,接着就是如何实现这个接口了,如下就是一个最简实现:
newObj[Symbol.iterator] = function(){ let index = 0 , self = this , keys = Object.keys( self ) ; return { next(){ if( index < keys.length ){ return { value: self[keys[index++]] , done: false }; } else{ return { value: undefined , done: true } } } }; };
仔细看一下发现就会发现 Symbol.iterator 接口其实是一个 Generator 函数,那么就可以简化代码:
newObj[Symbol.iterator] = function* (){ let keys = Object.keys( this ) ; for(let i = 0, l = keys.length; i < l; i++){ yield this[keys[i]]; } } for(let v of newObj){ console.log( v ); } // 输出结果 // 5 // 6
值得注意的是 Object.keys 碰巧解决了之前 for-in 遇到的继承问题
这样满足了我们的期望,使用 for-of 来遍历对象,但是好像哪里不对,我们遍历对象时一般都是期望同时输出 key 和 value 的,这样调整一下代码
newObj[Symbol.iterator] = function* (){ let keys = Object.keys( this ) ; for(let i = 0, l = keys.length; i < l; i++){ yield { key: keys[i] , value: this[keys[i]] }; } } for(let v of newObj){ console.log( v ); } // 输出结果 // {key: "e", value: 5} // {key: "f", value: 6}
这样返回了一个对象,似乎又很不舒服,我们能不能尝试一些解构赋值呢。。。
for(let {key, value} of newObj){ console.log(key, value ); } // 输出结果 // e 5 // f 6
这样似乎非常完美了。。。
扩展知识:for-of和其他循环的区别
循环名称 | 循环对象 | 是否可中断循环 | 是否有返回值 |
---|---|---|---|
for |
for 循环体的length
|
可以 | 无返回值 |
forEach |
仅可循环数组、map、set 等,不可循环字符串、普通对象 |
不可以 | 无返回值 |
do...while |
满足某种条件,则可一直循环,至少循环一次 | 可以 | 无返回值 |
while |
满足某种条件,则可一直循环 | 可以 | 无返回值 |
map |
组成新的数组成员,仅可循环数组,不可循环字符串、普通对象,set、map | 不可中断 | 返回新数组,不影响原数组 |
filter |
过滤数组成员,仅可循环数组,不可循环字符串、普通对象,set、map | 不可中断 | 返回新数组,不影响原数组 |
for...in |
可循环数组、对象 ,不可循环map、set 。可遍历数字键名,还可遍历手动添加的其他键,甚至包括原型链上的键 |
可以 | 无返回值 |
for...of |
循环可迭代的对象,不可循环普通对象(统一数据结构遍历) | 可以 | 无返回值 |
【相关推荐:javascript视频教程、web前端】
以上是es6的for of可以遍历对象吗的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

在ES6中,可以利用数组对象的reverse()方法来实现数组反转,该方法用于颠倒数组中元素的顺序,将最后一个元素放在第一位,而第一个元素放在最后,语法“array.reverse()”。reverse()方法会修改原始数组,如果不想修改需要配合扩展运算符“...”使用,语法“[...array].reverse()”。

async是es7的。async和await是ES7中新增内容,是对于异步操作的解决方案;async/await可以说是co模块和生成器函数的语法糖,用更加清晰的语义解决js异步代码。async顾名思义是“异步”的意思,async用于声明一个函数是异步的;async和await有一个严格规定,两者都离不开对方,且await只能写在async函数中。

为了浏览器兼容。ES6作为JS的新规范,加入了很多新的语法和API,但现代浏览器对ES6新特性支持度不高,所以需将ES6代码转为ES5代码。在微信web开发者工具中,会默认使用babel将开发者ES6语法代码转换为三端都能很好支持的ES5的代码,帮助开发者解决环境不同所带来的开发问题;只需要在项目中配置勾选好“ES6转ES5”选项即可。

步骤:1、将两个数组分别转为set类型,语法“newA=new Set(a);newB=new Set(b);”;2、利用has()和filter()求差集,语法“new Set([...newA].filter(x =>!newB.has(x)))”,差集元素会被包含在一个set集合中返回;3、利用Array.from将集合转为数组类型,语法“Array.from(集合)”。

在es6中,暂时性死区是一个语法错误,是指let和const命令使区块形成封闭的作用域。在代码块内,使用let/const命令声明变量之前,该变量都是不可用的,在变量声明之前属于该变量的“死区”;这在语法上,称为“暂时性死区”。ES6规定暂时性死区和let、const语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。

不是,require是CommonJS规范的模块化语法;而es6规范的模块化语法是import。require是运行时加载,import是编译时加载;require可以写在代码的任意位置,import只能写在文件的最顶端且不可在条件语句或函数作用域中使用;require运行时才引入模块的属性所以性能相对较低,import编译时引入模块的属性所所以性能稍高。

在es6中,可以利用array对象的length属性来判断数组里总共有多少项,即获取数组中元素的个数;该属性可返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。
