es6数组初始化_ES6 迭代器(Iterator)和 for...of循环使用方法
一、什么是迭代器?
生成器 概念在Java,Python等語言中都是具備的,ES6也添加到了JavaScript中。Iterator可以使我們 不需要初始化集合,以及索引的變量 ,而是使用迭代器對象的 next 方法,返回集合的下一項的值, 偏向程序化 。
迭代器 是帶有特殊接口的對象。含有一個next()方法,調用返回一個包含兩個屬性的對象,分別是value和done, value表示當前位置的值 , done表示是否迭代完 ,當為true的時候,調用next就無效了。
ES5中遍歷集合通常都是 for循環 ,數組還有 forEach 方法,對象就是 for-in ,ES6 中又添加了 Map 和 Set ,而迭代器可以統一處理所有集合數據的方法。迭代器是一個接口,只要你這個數據結構暴露了一個iterator的接口,那就可以完成迭代。ES6創造了一種新的遍歷命令for...of循環,Iterator接口主要供for...of消費。
二、如何使用迭代器?
1、默認 Iterator 接口
數據結構只要部署了 Iterator 接口,我們就成這種數據結構為"可遍歷"(Iterable)。ES6 規定,默認的 Iterator 接口部署在數據結構的 Symbol.iterator 屬性,或者說,一個數據結構只要具有 Symbol.iterator 數據,就可以認為是"可遍歷的"(iterable)。
可以供 for...of 消費的原生數據結構
- Array
- Map
- Set
- String
- TypedArray(一種通用的固定長度緩沖區類型,允許讀取緩沖區中的二進制數據)
- 函數中的 arguments 對象
- NodeList 對象
可以看上面的原生數據結構中并沒有對象(Object),為什么呢? 那是因為對象屬性的遍歷先后順序是不確定的,需要開發者手動指定。 本質上,遍歷器是一種線性處理,對于任何非線性的數據結構,部署遍歷器接口就等于部署一種線性變換 。 做如下處理,可以使對象供 for...of 消費:
// code1 function Obj(value) { this.value = value; this.next = null; } Obj.prototype[Symbol.iterator] = function() { var iterator = { next: next }; var current = this; function next() { if (current) { var value = current.value; current = current.next; return { done: false, value: value }; } else { return { done: true }; } } return iterator; } var one = new Obj(1); var two = new Obj(2); var three = new Obj(3); one.next = two; two.next = three; for (var i of one) { console.log(i); } // 1 // 2 // 32、調用 Iterator 接口的場合
(1) 解構賦值
// code2 let set = new Set().add('a').add('b').add('c'); let [x,y] = set; // x='a'; y='b' let [first, ...rest] = set; // first='a'; rest=['b','c'];(2) 擴展運算符
// code3 // 例一 var str = 'hello'; [...str] // ['h','e','l','l','o'] // 例二 let arr = ['b', 'c']; ['a', ...arr, 'd'] // ['a', 'b', 'c', 'd'](3)Generator 函數中的 yield* 表達式(下一章介紹)
// code4 let generator = function* () { yield 1; yield* [2,3,4]; yield 5; }; var iterator = generator(); iterator.next() // { value: 1, done: false } iterator.next() // { value: 2, done: false } iterator.next() // { value: 3, done: false } iterator.next() // { value: 4, done: false } iterator.next() // { value: 5, done: false } iterator.next() // { value: undefined, done: true }(4)其它場合
- for..of
- Array.from
- Map()、Set()、WeakMap()、WeakSet()
- Promise.all()
- Promise.race()
3、for...of 循環的優勢
先看看,數組 forEach 方法的缺點:
// code5 myArray.forEach(function (value) { console.log(value); });這個寫法的問題在于, 無法中途跳出 forEach 循環,break 命令或 return 命令都不能生效 。
再看看,對象 for...in 的循環的缺點:
for (var index in myArray) { console.log(myArray[index]); };- 數組的鍵名是數字,但是 for...in 循環是以字符串作為鍵名,"0"、"1"、"2"等。
- for...in 循環不僅可以遍歷數字鍵名,還會遍歷手動添加的期推薦,甚至包括原型鏈上的鍵。
- 某些情況下,for...in 循環會議任意順序遍歷鍵名
- for...in 遍歷主要是為遍歷對象而設計的,不適用于遍歷數組
那么, for...of 有哪些顯著的優點呢 ?
- 有著同 for...in 一樣的簡潔語法,但是沒有 for...in 那些缺點
- 不同于 forEach 方法,它可以與 break、continue 和 return 配合使用
- 提供了遍歷所有數據結構的統一操作接口
- for (var n of fibonacci) { if (n > 1000) { break; console.log(n); } }
4、各數據類型如何使用 for...of 循環?
(1)數組
- for...of 循環允許遍歷數組獲得鍵值
- var arr = ['a', 'b', 'c', 'd']; for (let a in arr) { console.log(a); // 0 1 2 3 } for (let a of arr) { console.log(a); // a b c d }
- for...of 循環調用遍歷器接口,數組的遍歷器接口只返回具有數字索引的值
- let arr = [3, 5, 7]; arr.foo = 'hello'; for (let i in arr) { console.log(i); // "0
總結
以上是生活随笔為你收集整理的es6数组初始化_ES6 迭代器(Iterator)和 for...of循环使用方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: elasticsearch最大节点数_E
- 下一篇: keil lib 只调用自己的函数_C语