摘要:迭代器和生成器一迭代器迭代器是帶有特殊接口的對象返回一個方法,該方法中同時又和屬性當再沒有值可以迭代時,為,為,否則為當前值,為根據上面的描述實現一個迭代器,如下二生成器生成器是返回迭代器的函數,如下生成器有幾點要注意的當執行流遇到語句時,
迭代器和生成器 一.迭代器
1.迭代器是帶有特殊接口的對象,返回一個next方法,該方法中同時又value和done屬性,當再沒有值可以迭代時,value為undefined,done為true,否則value為當前值,done為false
2.根據上面的描述實現一個迭代器,如下:
let iterator = { i: 0, items: [2, 4, 6], next() { let value, done; done = (this.i === this.items.length); value = done ? undefined : this.items[this.i++]; return { value: value, done: done } } }; console.log(iterator.next()); //{value: 2, done: false} console.log(iterator.next()); //{value: 4, done: false} console.log(iterator.next()); //{value: 6, done: false} console.log(iterator.next()); //{value: undefined, done: true}二.生成器
1.生成器是返回迭代器的函數,如下:
function *createIterator() { yield 1; yield 2; yield 3; } let iterator = createIterator(); console.log(iterator.next()); //{value: 1, done: false} console.log(iterator.next()); //{value: 2, done: false} console.log(iterator.next()); //{value: 3, done: false} console.log(iterator.next()); //{value: undefined, done: true}
2.生成器有幾點要注意的:
當執行流遇到yield語句時,該生成器就停止運轉了,直到迭代器再次調用next
可以再for循環中使用yield
yield只能用在生成器的內部,即使是生成器內部的函數也不行,即:yield無法跨越函數邊界
無法使用箭頭函數創建生成器
生成器可以存在于對象的屬性中
三.for-of循環1.可迭代類型:指那些包含Symbol.iterator屬性的對象,該屬性定義了返回迭代器的函數(如:數組,set,map等)
2.for-of循環可以循環可迭代類型,for-of循環會在可迭代類型每次執行后調用next()并將結果存儲在變量中,循環會持續進行,直到結果對象的done屬性為true
3.for-of循環會調用數組的Symbol.iterator屬性來獲取迭代器(該方法由幕后的js引擎調用),并將調用iterator.next(),并將該結果對象的value屬性的值賦給num,直到done為true,循環會退出,num不會被賦給undefined,代碼如下:
let values = [1, 2, 3]; for (let item of values) { console.log(item); //1 2 3 }
4.對于非可迭代對象,如null和undefined,使用for-of循環會拋出錯誤
5.可以在for-of循環中使用解構
let map = new Map(); map.set("name", "sxt"); map.set("age", 2); for(let [key, value] of map) { console.log(key + " = " + value); } //輸出: //name = sxt //age = 2
6.for-of循環可以用于循環NodeList
四.Symbol.iterator1.可以用Symbol.iterator屬性來訪問對象默認的迭代器,如:
let arr = [6, 7, 8]; let iterator = arr[Symbol.iterator](); console.log(iterator.next()); //{value: 6, done: false} console.log(iterator.next()); //{value: 7, done: false} console.log(iterator.next()); //{value: 8, done: false} console.log(iterator.next()); //{value: undefined, done: true}
2.判斷一個對象是否可以迭代,可以通過判斷Symbol.iterator屬性是否是一個函數來實現,如:
function isIterator(obj) { return typeof obj[Symbol.iterator] === "function"; } let arr = [1, 3, 4]; let num = 1; console.log(isIterator(arr)); //true console.log(isIterator(num)); //false
3.創建可迭代類型: 我們自己定義的對象默認是不可迭代類型,但是我們可以通過設置Symbol.iterator屬性來使這個對象可以迭代。因為前面第3點有講到,判斷一個對象是否可以迭代,其實是通過Symbol.iterator屬性來確定的,由此可以創建下面的對象
let obj = { *[Symbol.iterator]() { yield 1; yield 2; yield 3; } }; for (let item of obj) { console.log(item); //1 2 3 }五.內置迭代器
1.我們平常迭代數組,set和map時,能拿到迭代的值,是因為這些集合中有內置的迭代器,如
let arr = [1, 3, 5]; let set = new Set(); set.add("time"); set.add("user"); set.add("family"); let map = new Map(); map.set("name", "sxt"); map.set("age", 12); map.set("sister", "andy"); for(let item of arr) { console.log(item); // 1 3 5 } for(let item of set) { console.log(item); //time user family } for(let item of map) { console.log(item); //["name", "sxt"] ["age", 12] ["sister", "andy"] }
2.內置迭代器分為三種
entries()
keys()
values()
3.數組的entries返回的是[索引,值],set的entries是[值,值],因為set的鍵值是一樣的,map的entries是[鍵名,鍵值],如:
let arr = [1, 3, 5]; let set = new Set(); set.add("time"); set.add("user"); set.add("family"); let map = new Map(); map.set("name", "sxt"); map.set("age", 12); map.set("sister", "andy"); for(let item of arr.entries()) { console.log(item); // [0, 1] [1, 3] [2, 5] } for(let item of set.entries()) { console.log(item); //["time", "time"] ["user", "user"] ["family", "family"] } for(let item of map.entries()) { console.log(item); //["name", "sxt"] ["age", 12] ["sister", "andy"] }
4.數組的keys返回的索引,set的keys返回的還是值,map的keys返回的是值
5.數組,set,map的values返回的都是值
1.我們可以向迭代器中傳遞參數
function *createIterator() { let first = yield 1; let second = yield first + 2; yield second + 3; } let iterator = createIterator(); console.log(iterator.next()); //{value: 1, done: false} console.log(iterator.next(4)); //{value: 6, done: false} console.log(iterator.next(5)); //{value: 8, done: false} console.log(iterator.next()); //{value: undefined, done: true}
這里的難點是理解右側的代碼會和左邊的中斷
首次調用next的時候,不管傳入什么參數都會被忽略,因為傳入的參數會作為yield語句的返回值,而第一次只是yield 1,而沒有變量
七.包含return語句的生成器function *createIterator() { yield 1; return 133; yield 2; yield 3; } let iterator = createIterator(); console.log(iterator.next()); //{value: 1, done: false} console.log(iterator.next(4)); //{value: 133, done: true} console.log(iterator.next(5)); //{value: undefined, done: true} console.log(iterator.next()); //{value: undefined, done: true}
return會讓它提前執行完畢并針對next的調用返回一個值
八.生成器代理1.即,在一個生成器中調用另外的生成器,有時候,這樣的操作會更加的實用
function *create1() { yield 1; yield 2; yield 3; } function *create() { yield *create1(); yield true; } let iterator = create(); console.log(iterator.next()); //{value: 1, done: false} console.log(iterator.next()); //{value: 2, done: false} console.log(iterator.next()); //{value: 3, done: false} console.log(iterator.next()); //{value: true, done: false} console.log(iterator.next()); //{value: undefined, done: true}
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96201.html
摘要:我個人認為迭代器和生成器是新增的特性里面,非常重要的部分,充分地掌握和使用迭代器和生成器,是十分必要和重要的,所以我會寫關于二者的一系列文章。 我個人認為迭代器和生成器是es6新增的特性里面,非常重要的部分,充分地掌握和使用迭代器和生成器,是十分必要和重要的,所以我會寫關于二者的一系列文章。話不多說,先來了解一下基本概念:一:什么是迭代器 1: 迭代器是一個對象 2: 迭代器有一個屬性...
摘要:生成器的內部一直在停頓和恢復之間切換,直到循環完成或停頓位置缺點生成器不能滿足所有迭代器的需求,因為如果不查詢,生成器永遠不知道下一個要迭代的值是什么,在生成器中無法后退或前進。 一.迭代器 分析:想一下,如果把集合對象和對集合對象的操作放在一起,當我們想換一種方式遍歷集合對象中元素時,就需要修改集合對象了,違背單一職責原則,而迭代器模式將數據結構和數據結構的算法分離開,兩者可獨立發展...
摘要:來說說迭代器和生成器,還有可迭代對象和生成器表達式。有點繞是不是,其實,一般只要知道可迭代對象以及它是如何實現的就行了,中常常用生成器來代替迭代器,可以說,生成器就是迭代器。 來說說迭代器和生成器,還有可迭代對象和生成器表達式。 之前簡單的提到過,一個對象是可迭代的可以理解為能夠使用for循環。這樣說其實不太準確,某個對象可迭代是因為它內部實現了$__iter__$這個特殊方法。比如在...
摘要:本文重點掌握可迭代的對象的定義掌握可迭代對象迭代器與生成器之間的關系和異同熟悉標準庫中生成器。二迭代器迭代器介紹迭代器用于從集合中取出元素的對象。若想再次迭代須重建迭代器。迭代器檢查方式調用,。區別可迭代的對象不是迭代器。 導語:本文章記錄了本人在學習Python基礎之控制流程篇的重點知識及個人心得,打算入門Python的朋友們可以來一起學習并交流。 本文重點: 1、掌握可迭代的對象的...
摘要:迭代器迭代器用于循環構建和擴展集合類型逐行遍歷文本文件列表推導字典推導和集合推導元組拆包調用函數時,使用拆包實參解釋器需要迭代對象時,會自動調用內置的函數,有以下功能檢查對象是否實現了方法,如果實現了就調用它,獲取一個迭代器。 迭代器 迭代器用于: for 循環 構建和擴展集合類型 逐行遍歷文本文件 列表推導、 字典推導和集合推導 元組拆包 調用函數時, 使用 * 拆包實參 解釋器...
摘要:在生成器中使用語句生成器也是函數,所以它也可以使用語句。只是由于生成器本身的特性,其內部的的行為會和一般函數有些差別。 前面2篇系列文章講解了迭代器和生成器的最常用,最基礎的用法;這篇來討論迭代器和生成器的一些稍稍高級一點的用法: 1: 給迭代器的next()方法傳參 2: 從迭代器中拋出錯誤 3: 在生成器中使用return語句 4: 委托生成器(組合生成器或者生成器組合?) 1: ...
閱讀 1369·2021-10-13 09:39
閱讀 1333·2021-09-23 11:22
閱讀 2243·2019-08-30 14:05
閱讀 1059·2019-08-29 17:03
閱讀 771·2019-08-29 16:24
閱讀 2227·2019-08-29 13:51
閱讀 656·2019-08-29 13:00
閱讀 1290·2019-08-29 11:24