深入浅出ES6——迭代器的演变

在JavaScript刚刚开始萌生的时候,我们通常使用这种方式遍历数组

let arr1 = [1, 2, 3, 4];

for (let index = 0; index < arr1.length; index++) {
    const element = arr1[index];
    console.log(element); // 1 2 3 4
}

自从ES5 正式发布之后,我们可以使用 forEach 方法来遍历数组.

let arr2 = [1, 2, 3, 4];

arr2.forEach( item => {
    if (item === 3) return
    console.log(item); // 1 2 4
})
  • 显然的,这段代码看起来更加简洁,但是并没有按照我们预期的进行终结遍历。
  • 在文档中我们可以看到描述 forEach() 方法对数组的每个元素执行一次提供的函数。 意思就是即使你在某个函数中return了也只是终结了当次函数的执行。

那么,你一定想尝试一下 for-in 循环

let arr3 = [1, 2, 3, 4];

for (const index in arr3) {
    if (index === 3) break
    console.log(index);   // 0 1 2 3
    console.log(typeof index); // string
}

程序再次没有按照我们预期的运行:

  • 在这段代码中,赋值给index的值并不是实际的数字,可以看到输出的是string '0' '1' '2' '3', 因此如果在这之前你并没深入理解,可能会掉进坑里,此时我们可以把 === 改成 == 即可

  • for...in 循环只遍历可枚举属性。像Array和Object使用内置构造函数所创建的对象都会继承自Object.prototype 和 String.prototype的不可枚举属性, 如果在原型上自定义了属性,那么稍微不注意将会导致如下错误:

let arr3 = [1, 2, 3, 4];

Array.prototype.name = '看看我被遍历了没';

for (const key in arr3) {

    // 将额外的遍历属性
    // const element = arr3[key];
    // console.log(element); // 1 2 3 4 '看看我被遍历没'

    // 正确做法
    if (arr3.hasOwnProperty(key)) {
        const element = arr3[key];
        console.log(element); // 1 2 3 4
    }
}

  • 更加可怕的是,由于迭代的顺序是依赖于执行环境的,所以数组遍历不一定按次序访问元素。

  • 简而言之, for-in 是为普通对象设计的,你可以遍历得到字符串类型的键,因此不适用于数组遍历。

更好的选择 for-of 循环

在ES6中增加了一种新的循环语法来解决目前的问题:

for (variable of iterable) {
    //statements
}

for...of 可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句。

  • 这是最简洁、最直接的遍历数组元素的语法

  • 这个方法避开了 for-in 循环的所有缺陷

  • 与forEach不同的是,它可以正确响应 break、continue 和 return 语句

  • 未来的 JS 可以使用一些新型的集合类,甚至会有更多的类型
    陆续诞生,而 for-of 就是为遍历所有这些集合特别设计的循环语句

  • for-of 循环不支持普通对象,但如果你想迭代一个对象的属性,你可以用 for-in 循环(这也是它的本职工作)或内建的 Object.keys()方法:

// 向控制台输出对象的可枚举属性
for (var key of Object.keys(someObject)) {
    console.log(key + ": " + someObject[key]);
}

深入理解

“能工摹形,巧匠窃意.” -- 巴勃罗·毕加索

ES6始终坚信这样的宗旨: 凡是新加入的特性,势必已在其他语言中得到强有力的实用性证明。
举个例子,新加入的for-of 循环像极了C++、Java、C#以及Python中的循环语句。与他们一样,这里的 for-of 循环支持语言和标准库中提供的几种不同的数据结构,它同样也是这门语言中的一个扩展点。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345