摘要:搞這么神秘其實就是個迭代器的核心實際上就是一個,通過關鍵字能夠把函數體拆成完全可控執行片段,在函數體外部通過來對這些執行片段進行遍歷這和遍歷這些數據結構是一個道理只不過用來遍歷函數片段,而用來遍歷元素對生成器執行操作,進行生成器的入口開始執
Generator
搞這么神秘 其實就是個迭代器
Generator的核心實際上就是一個Iterator,通過yield關鍵字能夠把函數體拆成完全可控執行片段,在函數體外部通過next來對這些執行片段進行遍歷. 這和遍歷array,set,map這些數據結構是一個道理.只不過generator用來遍歷函數片段,而array/set/map 用來遍歷元素.
對生成器執行next()操作,進行生成器的入口開始執行代碼
執行到第一個yield時,向調用者返回一個值,并將函數掛起;
掛起時,函數當前的執行上下文環境和參數被保存下來;
執行到第二個yield時,參數從掛起狀態被重新調用,進入上次掛起的執行上下文環境繼續下面的操作,到下一個yield操作時重復上面的過程
執行過程解析function *generator() { console.log(1); var x = (yield 2) +3 console.log(3); var y = yield 4; } var g = generator(); console.log(g.next()); console.log(g.next()); console.log(g.next()); console.log(g.next());
var g = generator() 這一句毛都不會輸出,實際上這句話執行完之后,generator()形成了內存泄漏狀態,因為函數體內部的對象被外部全局變量(g)所引用,導致generator()無法被回收. 這一句執行完后實際上 g = {next:function(){xxxxxx}},
第一個g.next()會執行console.log(1),向下執行到yield關鍵字,將{value:2,done:false}返回給外部,然后掛起當前函數
第二個g.next()會執行 (yield 2)+3 的操作,會執行把 (yield 2)+3 賦值給x的操作, 會執行console.log(3)的操作,向下執行到yield關鍵字,把{value:4,done:false}返回給外部,掛起當前函數.
第三個g.next()會執行把(yield 4)賦值給y的操作,向下掃描執行,沒有發現有yield或者return了,這時候會throw一個stopIterator的異常,表示在這之后已經沒有yield或者return語句可以迭代了,于是把done值置為true. 返回{value:undefined,done:true}
第四個g.next()同理,返回{value:undefined,done:true}
function *generator(z) { console.log(1); var x = (yield 2) +z console.log(x); console.log(3); var y = yield 4; console.log(y) } var g = generator(5); console.log(g.next(7)); console.log(g.next(8)); console.log(g.next(9)); console.log(g.next(10));
var g = generator(5)這一句毛都不輸出,實際上這句話執行完之后,generator()形成了內存泄漏狀態,因為函數體內部的對象被外部全局變量(g)所引用,導致generator()無法被回收. 這一句執行完后實際上 g = {next:function(){xxxxxx}}, 且函數體內的z參數被初始化成5.
第一個g.next(7)進入函數,會執行console.log(1),向下執行掃描到了yield關鍵字,于是將{value:2,done:false}返回給外部,然后掛起當前函數
第二個g.next(8)從上次掛起的地方進入函數,會執行 把next的參數8賦值給(yield 2)的操作, 會執行 (yield 2)+z 的操作, 會執行 把(yield 2)+z的結果賦值給x的操作, 會執行console.log(x)的操作,會執行console.log(3)的操作,繼續向下執行掃描到了yield關鍵字,于是將{value:4,done:false}返回給外部,然后掛起當前函數
第三個g.next(9)從上次掛起的地方進入函數,會執行把next的參數9賦值給(yield 4)操作,會執行把(yield 4)賦值給y的操作,會執行console.log(y)的操作. 然后把向下執行掃描,沒有發現有yield或者return了,這時候會throw一個stopIterator的異常,表示在這之后已經沒有yield或者return語句可以迭代了,于是把done值置為true. 返回{value:undefined,done:true},然后掛起當前函數
第四個g.next(10)從上次掛起的地方進入函數,也是同理,返回{value:undefined,done:true},然后掛起當前函數
相關參考由于Iterator/Generator無一例外的都涉及到了javascript函數從創建到執行到銷毀的過程, 涉及到了 執行上下文EC/活動對象AO/變量對象VO/內存泄漏/回收機制 等核心概念,東西多且較復雜,有興趣的同學可以參考湯姆大叔深入理解JavasSript系列, 里面有對javascript的核心(函數/原型鏈)等做了詳盡的介紹.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/111477.html
摘要:搞這么神秘其實就是個迭代器的核心實際上就是一個,通過關鍵字能夠把函數體拆成完全可控執行片段,在函數體外部通過來對這些執行片段進行遍歷這和遍歷這些數據結構是一個道理只不過用來遍歷函數片段,而用來遍歷元素對生成器執行操作,進行生成器的入口開始執 Generator 搞這么神秘 其實就是個迭代器 Generator的核心實際上就是一個Iterator,通過yield關鍵字能夠把函數體拆成完全...
摘要:搞這么神秘其實就是個迭代器的核心實際上就是一個,通過關鍵字能夠把函數體拆成完全可控執行片段,在函數體外部通過來對這些執行片段進行遍歷這和遍歷這些數據結構是一個道理只不過用來遍歷函數片段,而用來遍歷元素對生成器執行操作,進行生成器的入口開始執 Generator 搞這么神秘 其實就是個迭代器 Generator的核心實際上就是一個Iterator,通過yield關鍵字能夠把函數體拆成完全...
摘要:任何數據結構只要部署接口,就可以完成遍歷操作即依次處理該數據結構的成員。的遍歷某個數據結構過程是這樣的比如對進行遍歷創建一個指針對象,指向當前數組的起始位置。 Iterator 這真是毅種循環 Iterator不是array,也不是set,不是map, 它不是一個實體,而是一種訪問機制,是一個用來訪問某個對象的接口規范,為各種不同的數據結構提供統一的訪問機制。任何數據結構只要部署Ite...
摘要:任何數據結構只要部署接口,就可以完成遍歷操作即依次處理該數據結構的成員。的遍歷某個數據結構過程是這樣的比如對進行遍歷創建一個指針對象,指向當前數組的起始位置。 Iterator 這真是毅種循環 Iterator不是array,也不是set,不是map, 它不是一個實體,而是一種訪問機制,是一個用來訪問某個對象的接口規范,為各種不同的數據結構提供統一的訪問機制。任何數據結構只要部署Ite...
摘要:任何數據結構只要部署接口,就可以完成遍歷操作即依次處理該數據結構的成員。的遍歷某個數據結構過程是這樣的比如對進行遍歷創建一個指針對象,指向當前數組的起始位置。 Iterator 這真是毅種循環 Iterator不是array,也不是set,不是map, 它不是一個實體,而是一種訪問機制,是一個用來訪問某個對象的接口規范,為各種不同的數據結構提供統一的訪問機制。任何數據結構只要部署Ite...
閱讀 1849·2023-04-26 01:58
閱讀 1981·2019-08-30 11:26
閱讀 2729·2019-08-29 12:51
閱讀 3495·2019-08-29 11:11
閱讀 1182·2019-08-26 11:54
閱讀 2095·2019-08-26 11:48
閱讀 3478·2019-08-26 10:23
閱讀 2384·2019-08-23 18:30