亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        ECMAScript 6集合遍歷機(jī)制分析

        2021-03-10 09:20:22張曉靜
        電子技術(shù)與軟件工程 2021年20期
        關(guān)鍵詞:機(jī)制方法

        張曉靜

        (92981 部隊(duì) 北京市 100161)

        ECMAScript 是 通 過Ecma 國 際(Ecma International, 前身為歐洲計(jì)算機(jī)制造商協(xié)會(huì),European computer manufacturers association)制訂的ECMA-262 協(xié)議標(biāo)準(zhǔn)化的腳本程序設(shè)計(jì)語言[1],JavaScript 的語法和語義是ECMAScript 規(guī)范的實(shí)現(xiàn)。自1997年起至今ECMAScript 不斷更新并發(fā)布了多個(gè)版本。2011年ECMAScript 5.1 版本(ES5)成為了ISO 國際標(biāo)準(zhǔn)(ISO/IEX 16262),并在萬維網(wǎng)上得到廣泛應(yīng)用。2015年ECMAScript 6 版本(ES6)是繼ES5 之后的一次重大改進(jìn),旨在讓JavaScript 成為企業(yè)級(jí)開發(fā)語言而不再局限于瀏覽器端,而后發(fā)布的版本都是在ES6 的基礎(chǔ)上新增較少特性。ES6 經(jīng)迅速普及,目前基本已成為業(yè)界標(biāo)準(zhǔn)。

        遍歷是一種循環(huán)裝置,能夠順序訪問集合中每一個(gè)元素。編程語言往往通過提供一種機(jī)制來支持遍歷集合,將內(nèi)部實(shí)現(xiàn)細(xì)節(jié)隱藏在類的私有部分[2],開發(fā)人員只需調(diào)用公共方法,而對(duì)于架構(gòu)師級(jí)別的開發(fā)人員來說,了解底層實(shí)現(xiàn)是必要的。本文旨在通過剖析ES6 遍歷機(jī)制的內(nèi)部實(shí)現(xiàn)細(xì)節(jié),來為深入理解ES6 語言設(shè)計(jì)思路和未來工作提供堅(jiān)實(shí)的理論基礎(chǔ)。

        1 遍歷語句和方法

        1.1 遍歷語句對(duì)比分析

        遍歷語句通常在大括號(hào)內(nèi)部寫入每次循環(huán)需要做什么,通過continue、break 語句改變遍歷正常進(jìn)行過程。ES5 中集合主要是Array(數(shù)組)和Object(對(duì)象),遍歷語句主要有for、while、dowhile 及for-in,表1 為ES5 及ES6 的遍歷語句對(duì)比分析。

        表1:遍歷語句對(duì)比

        for 需要規(guī)定指針賦值語句、執(zhí)行條件表達(dá)式和計(jì)數(shù)器更新表達(dá)式,如果是多層嵌套循環(huán),則每一層都需要這些表達(dá)式或語句。for、while、do-while 語句是最傳統(tǒng)和簡(jiǎn)易的遍歷語句,底層處理功能較少,語法相對(duì)繁瑣,但這樣詳細(xì)的控制方式使得輸出方式更靈活。

        for-in 語句遍歷輸出對(duì)象的可枚舉屬性,包括其自身屬性和原型鏈上繼承的屬性,所有屬性都會(huì)轉(zhuǎn)換為字符串輸出。其遍歷順序是一個(gè)相對(duì)復(fù)雜的規(guī)則:首先,遍歷對(duì)象自身的可枚舉屬性,如果是非負(fù)整數(shù)屬性或能夠轉(zhuǎn)換為非負(fù)整數(shù)的字符串屬性,則先按照數(shù)值的升序順序遍歷,接著對(duì)不能轉(zhuǎn)換為非負(fù)整數(shù)的字符串屬性,按照元素加入對(duì)象的順序遍歷;然后,依照上述規(guī)則逐層遍歷對(duì)象原型鏈上的可枚舉屬性,直到頂層Object 的可枚舉屬性也遍歷結(jié)束。for-in 的語法較為簡(jiǎn)潔,但遍歷順序不是直觀的元素加入順序,且會(huì)遍歷原型鏈上的可枚舉屬性,這不一定是開發(fā)人員需要的。圖1為for-in 遍歷對(duì)象舉例,輸出結(jié)果順序與上述規(guī)則一致。

        圖1:for-in 遍歷對(duì)象舉例

        ES6 新增集合主要有Set、Map,以及for-of 遍歷語句。for-of語句能夠遍歷任何可遍歷對(duì)象,語法和for-in 一樣簡(jiǎn)潔,而它輸出順序固定,支持多種輸出形式,是ES6 標(biāo)準(zhǔn)下遍歷的最佳選擇。

        1.2 遍歷方法對(duì)比分析

        傳統(tǒng)ES5 遍歷方法需要傳遞一個(gè)回調(diào)函數(shù)作為參數(shù),回調(diào)函數(shù)中寫入每次循環(huán)時(shí)需要做什么,并寫入return 語句返回循環(huán)結(jié)果。表2 為ES5 與ES6 的遍歷方法對(duì)比分析,ES5 遍歷的方法主要有:forEach、map、filter、some、every;ES6 針對(duì)Array 新增了find、findIndex,并對(duì)Set、Map、Array 都提供了entries、keys 和values方法。

        表2:遍歷方法對(duì)比

        forEach 方法可以遍歷Set、Map 和Array,回調(diào)函數(shù)內(nèi)return語句代表退出本次循環(huán)而不是中斷遍歷,中斷遍歷需要拋出異常,這是一種不友好的編程風(fēng)格。map 方法用于映射一個(gè)新的數(shù)組,return 語句代表本次循環(huán)元素映射值。some 方法用于查找符合條件的元素, return 語句返回一個(gè)布爾值,代表當(dāng)前元素是否符合條件,找到符合條件的元素時(shí)中斷遍歷。ES6 新增的find、findIndex 方法也是用于查找。every 方法用于測(cè)試集合元素,return 語句返回一個(gè)布爾值,代表是否通過測(cè)試,找到測(cè)試不通過的元素時(shí)中斷遍歷。以上方法使用場(chǎng)景固定,語法相對(duì)刻板,且中斷遍歷方式不大友好。

        ES6 新增的keys、values、entries 分別是用于遍歷集合元素的鍵名、鍵值、鍵值對(duì),Array、Set、Map 集合都增加了這三個(gè)遍歷方法,方法通過實(shí)例調(diào)用,不再以傳遞回調(diào)函數(shù)作為參數(shù)的方式調(diào)用。此外,Object 也新增了這三類方法。ES6 新增的遍歷方法從根本上滿足了集合遍歷的需求。

        2 ES6遍歷機(jī)制

        ES6 標(biāo)準(zhǔn)下的集合主要有Array、Object、Set、Map,開發(fā)人員基于實(shí)際需求,可能還需要組合使用這些集合,即自定義一個(gè)較為復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。處理不同的數(shù)據(jù)結(jié)構(gòu),需要一個(gè)統(tǒng)一的遍歷接口機(jī)制。ES6 新增的Iterator(遍歷器),旨在提供這樣一個(gè)統(tǒng)一的機(jī)制,這與Java 等后端語言具有相似性。

        2.1 遍歷器協(xié)議

        一個(gè)遍歷器對(duì)象應(yīng)包含一個(gè)名為next 的方法,而next 方法返回一個(gè)具有value、done 兩個(gè)屬性值的對(duì)象,其中value 為當(dāng)前集合元素值,done 是代表遍歷是否結(jié)束的布爾值,而返回一個(gè)遍歷器對(duì)象的方法稱為遍歷器方法,這一規(guī)則稱為遍歷器協(xié)議。遍歷器對(duì)象相當(dāng)于一個(gè)指針,在遍歷過程中指向當(dāng)前循環(huán)的元素,調(diào)用其next 方法則移動(dòng)指針,直到done 的值為true,代表遍歷結(jié)束。圖2為一個(gè)自定義遍歷器方法。

        圖2:自定義遍歷器方法

        2.2 可遍歷協(xié)議

        遍歷器協(xié)議只是規(guī)定了集合遍歷方法的編寫規(guī)則,在此情況下,想要調(diào)用一種集合的遍歷器方法,要知道方法名稱、然后執(zhí)行得到遍歷器對(duì)象、再逐步調(diào)用遍歷器對(duì)象的next 方法。在集合種類多或自定義數(shù)據(jù)結(jié)構(gòu)的情況下,僅有遍歷器協(xié)議并不足夠。

        Iterable(可遍歷)協(xié)議定義了一個(gè)默認(rèn)的遍歷器接口,約定將集合的默認(rèn)遍歷器方法都部署在該集合原型對(duì)象的Symbol.iterator屬性上。當(dāng)一個(gè)數(shù)據(jù)結(jié)構(gòu)具有Symbol.iterator 屬性,則認(rèn)為它是可遍歷的。其中,Symbol 是ES6 新增的原始數(shù)據(jù)類型,用于表示獨(dú)一無二的屬性,Symbol.iterator 是約定作為集合默認(rèn)遍歷器方法的屬性名稱。Symbol 類型的屬性是可枚舉屬性,但for-in 語句遍歷時(shí)排除了這類屬性??杀闅v協(xié)議是ES6 實(shí)現(xiàn)統(tǒng)一遍歷機(jī)制的核心。

        針對(duì)一個(gè)可遍歷對(duì)象,底層執(zhí)行遍歷的過程如下:

        (1)調(diào)用該對(duì)象Symbol.iterator 屬性的方法,獲取遍歷器對(duì)象;

        (2)調(diào)用遍歷器對(duì)象的next 方法,獲得包含value 和done 的返回值,done 的值為true 則退出循環(huán),否則輸出value 值;

        (3)重復(fù)第2 步直到 done 值為true。ES6 中所有支持可遍歷對(duì)象的場(chǎng)合,都是按照這一過程執(zhí)行,例如for-of 語句。

        2.3 內(nèi)置遍歷機(jī)制

        2.3.1 數(shù)據(jù)結(jié)構(gòu)的內(nèi)置遍歷器方法

        ES6 為一些數(shù)據(jù)結(jié)構(gòu)內(nèi)置了遍歷器方法,數(shù)據(jù)結(jié)構(gòu)主要有String、Array、Set、Map,以及函數(shù)的arguments 參數(shù)類數(shù)組、文檔對(duì)象模型的NodeList(節(jié)點(diǎn)列表)類數(shù)組,內(nèi)置遍歷器方法有keys、values 和entries,以及Symbol.iterator,內(nèi)置的遍歷器方法與默認(rèn)遍歷器方法根據(jù)實(shí)際需要可能是同一個(gè)方法實(shí)例。

        圖3 為String 等數(shù)據(jù)結(jié)構(gòu)內(nèi)置遍歷器方法原型鏈。String 類型遍歷時(shí)只需要輸出每個(gè)字符,因此僅有Symbol.iterator 屬性上部署的默認(rèn)遍歷器方法。Set 是元素不重復(fù)的類數(shù)組,鍵值與鍵名相同,因此Set 原型的keys 和values 屬性指向同一個(gè)內(nèi)置的名為values 的遍歷器方法,通常遍歷Set 集合期望輸出的是元素值,因此values方法還應(yīng)作為默認(rèn)的遍歷器方法,即Symbol.iterator 屬性也指向values 方法。Array、Map 的遍歷器方法內(nèi)置模式與Set 大致相同,并根據(jù)自身特點(diǎn)分別指定了默認(rèn)遍歷器方法。這四種數(shù)據(jù)結(jié)構(gòu)都有默認(rèn)遍歷器方法,因此它們的實(shí)例對(duì)象都是可遍歷的。

        圖3:數(shù)據(jù)結(jié)構(gòu)內(nèi)置遍歷器方法原型鏈

        2.3.2 內(nèi)置遍歷器對(duì)象的遍歷機(jī)制

        ES6 針對(duì)String 等數(shù)據(jù)結(jié)構(gòu)增加了內(nèi)置遍歷器原型對(duì)象,是隱藏在原型鏈內(nèi)部的底層實(shí)現(xiàn),內(nèi)置遍歷器對(duì)象通過調(diào)用內(nèi)置遍歷器方法生成。ES6 還實(shí)現(xiàn)了內(nèi)置遍歷器對(duì)象的遍歷機(jī)制,使得內(nèi)置遍歷器對(duì)象本身也可遍歷。例如,一個(gè)數(shù)組實(shí)例a,a 是可遍歷的,a.entries()也是可遍歷的。

        圖4 為String、Array、Set、Map 四種數(shù)據(jù)結(jié)構(gòu)內(nèi)置遍歷器對(duì)象原型鏈??梢钥闯觯珽S6 設(shè)置了一個(gè)無名對(duì)象繼承Object,這個(gè)無名對(duì)象僅有一個(gè)Symbol.iterator 屬性,該屬性對(duì)應(yīng)方法的功能只是返回this,即返回對(duì)象本身,這四種數(shù)據(jù)結(jié)構(gòu)的遍歷器對(duì)象原型都繼承了這個(gè)無名對(duì)象,同時(shí)遍歷器原型本身都有一個(gè)next 方法,不同數(shù)據(jù)結(jié)構(gòu)的內(nèi)置遍歷器原型實(shí)現(xiàn)不同的next 方法來規(guī)定其元素遍歷順序。

        圖4:內(nèi)置遍歷器對(duì)象原型鏈

        這一機(jī)制使得內(nèi)置遍歷器對(duì)象遵循了可遍歷協(xié)議,例如,一個(gè)數(shù)組實(shí)例a,使用for-of 語句遍歷a.entries()時(shí),首先,執(zhí)行a.entries()獲得a 的遍歷器對(duì)象aItr;然后,執(zhí)行aItr[Symbol.iterator](),底層調(diào)用時(shí)將從aItr 自身出發(fā)在原型鏈上逐層向上查找,最終找到無名對(duì)象上的Symbol.iterator 方法,該方法返回this,即執(zhí)行結(jié)果仍為aItr;最后,循環(huán)執(zhí)行aItr.next(),逐個(gè)獲取元素值,同樣地,底層調(diào)用next 方法時(shí)從自身出發(fā)在原型鏈上向上查找,實(shí)際調(diào)用了Array Iterator(數(shù)組遍歷器)原型上的next 方法。

        2.4 遍歷體系結(jié)構(gòu)及使用場(chǎng)合

        for-of 是可遍歷對(duì)象最常見的使用場(chǎng)合,此外還有數(shù)組形式解構(gòu)、擴(kuò)展運(yùn)算符、Array.from()方法、Generator(生成器)中的yield*表達(dá)式等等。圖5 表達(dá)了ES6 遍歷機(jī)制的整體結(jié)構(gòu),其中,數(shù)據(jù)結(jié)構(gòu)的內(nèi)置遍歷器方法、遍歷器對(duì)象的遍歷方法或自定義對(duì)象的遍歷器方法都是通過Symbol.iterator 屬性及其相應(yīng)方法作為接口接入了ES6 遍歷體系,讓數(shù)據(jù)對(duì)象、遍歷器對(duì)象、自定義對(duì)象都成為了可遍歷的對(duì)象,于是可以在所有ES6 中支持遍歷的場(chǎng)合被遍歷,這些使用場(chǎng)合都會(huì)在底層執(zhí)行2.2 中描述的遍歷執(zhí)行過程。

        圖5:ES6 遍歷體系結(jié)構(gòu)圖

        3 結(jié)語

        相比ES5,ES6 在遍歷方面新增了很多新特性,并通過可遍歷協(xié)議實(shí)現(xiàn)了統(tǒng)一遍歷機(jī)制,建立起完整的遍歷體系,開發(fā)人員通過對(duì)自定義數(shù)據(jù)結(jié)構(gòu)設(shè)置默認(rèn)遍歷器方法來接入這一體系,實(shí)現(xiàn)多場(chǎng)合靈活輸出。生成器對(duì)象也是一種遍歷器對(duì)象,而生成器對(duì)象內(nèi)置遍歷方法的實(shí)現(xiàn)方式,以及異步遍歷器的實(shí)現(xiàn)細(xì)節(jié),可以作為下一步研究?jī)?nèi)容。

        猜你喜歡
        機(jī)制方法
        構(gòu)建“不敢腐、不能腐、不想腐”機(jī)制的思考
        學(xué)習(xí)方法
        自制力是一種很好的篩選機(jī)制
        文苑(2018年21期)2018-11-09 01:23:06
        可能是方法不對(duì)
        定向培養(yǎng) 還需完善安置機(jī)制
        用對(duì)方法才能瘦
        Coco薇(2016年2期)2016-03-22 02:42:52
        破除舊機(jī)制要分步推進(jìn)
        四大方法 教你不再“坐以待病”!
        Coco薇(2015年1期)2015-08-13 02:47:34
        賺錢方法
        捕魚
        国产免费人成视频在线播放播| 国产永久免费高清在线| 国内精品久久久久影院一蜜桃| 欧美伊人网| 日本一区不卡高清在线观看| 国模91九色精品二三四| 久久亚洲欧美国产精品| 特级毛片a级毛片免费播放| 天堂av一区二区在线观看| 97久久综合精品国产丝袜长腿| 人人澡人人妻人人爽人人蜜桃麻豆| 无码人妻一区二区三区在线视频| 91精品国产91久久久无码95 | 日韩av无码成人无码免费| 亚洲成a人网站在线看| 亚洲av综合av国一区二区三区| 厨房人妻hd中文字幕| 国模少妇一区二区三区| 国产精品亚洲ΑV天堂无码| av成人综合在线资源站| 国产精品 亚洲 无码 在线| 亚洲精品无码国模| 亚洲最大av免费观看| 国产成人自拍视频播放| 一区二区三区乱码在线 | 欧洲 | 亚洲av色影在线| 妓院一钑片免看黄大片| 欧洲国产成人精品91铁牛tv| 久久99精品综合国产女同| 又粗又黄又猛又爽大片app| 好男人视频在线视频| 国产av91在线播放| 最好看的亚洲中文字幕| 精品9e精品视频在线观看| 亚洲人妻无缓冲av不卡| 日韩人妻一区二区中文字幕| 日本久久久久亚洲中字幕| 狠狠色婷婷久久一区二区| 日本一区二区三区的免费视频观看 | 国产亚洲曝欧美不卡精品| 熟女一区二区中文字幕|