JavaScript中for of和for in的區(qū)別詳解
首先介紹一下for of
for of 是在es6中新加入的東西,如果說for of 給我們最直觀的體現(xiàn)就是使用for of 去遍歷數(shù)組的話,直接打印輸出的是value值,這一點(diǎn)和for in打印輸出的是索引值index是不同的,這是對于我們這些初學(xué)者最直觀的感受。
其次for of
最本質(zhì)的區(qū)別就是他不能用來直接遍歷普通的對象
,而只能遍歷部署了iterator(迭代器)
接口的類數(shù)組對象.
那么什么是iterator
呢?
迭代器(Iterator)就是這樣一種機(jī)制。它是一種接口,為各種不同的數(shù)據(jù)結(jié)構(gòu)提供統(tǒng)一的訪問機(jī)制。任何數(shù)據(jù)結(jié)構(gòu)只要部署 Iterator 接口,就可以完成遍歷操作(即依次處理該數(shù)據(jù)結(jié)構(gòu)的所有成員)
下面的例子正好說明for of 是不能遍歷普通的對象的:
let obj2 = { x: 1,y: 2, z: 3,}; for (const value of obj2) { ?console.log(value); } //遍歷時出錯 //Uncaught TypeError: obj2 is not iterable
這是因為普通對象不是 可迭代對象
,這里面提到的可迭代對象是一種實現(xiàn)了迭代器協(xié)議
的對象,其中的迭代器協(xié)議要求對象部署了這個iterator
,而這個方法是掛載在原型下Symbol(Symbol.iterator)
方法,因此我們在使用for of 去處理比如說是數(shù)組的時候,其實就是調(diào)用了數(shù)組原型下的這個方法,每當(dāng)調(diào)用這個方法之后,方法內(nèi)部就會返回next方法,這就相當(dāng)于是''指針'', 下次在調(diào)用的時候''指針''就后移動
對此,可能很多同學(xué)還是感覺蒙蒙的,這里舉一個例子來說明:
let obj = { ?data: [1, 2, 3], ?// 這里給對象實現(xiàn)了一個迭代器方法 [Symbol.iterator]() { ? ?let index = 0; ? ?const data = this.data; ? ?return { ? ? ?next() { ? ? ? ?if (index < data.length) { ? ? ? ? ?return { ?value: data[index++], done: false, }; ? ? ? } else { ? ? ? ? ?return { done: true }; ? ? ? } ? ? }, ? }; }, }; for (const value of obj) { ?console.log(value); }//1 2 3
在經(jīng)過這樣的處理之后,我們就給對象實現(xiàn)了迭代器的方法。這樣我們就可以使用for of 來對這個obj對象的遍歷,大家看完這段代碼肯定是一頭霧水,這主要是對Symbol.iterator
和next方法
的不了解,我就來簡單的介紹一下這兩個方法。
Symbol.iterator
這個是什么呢?其實這個屬性是一個函數(shù),他的返回值是一個迭代器對象
,我們在對象中定義這個屬性之后,當(dāng)我們使用for of
的時候,語言機(jī)制會去尋找一種方法,這個方法就是next方法
,當(dāng)我們在對象中使用這個屬性的時候,其實就是覆蓋了默認(rèn)的迭代器,這樣我們就可以實現(xiàn)自己的邏輯代碼。- 其次我們要注意返回的迭代器對象:我們要知道,迭代器對象是要
帶有next方法的對象
,而且這個next方法的返回值還必須是一個包含value和done的對象
。其中value是當(dāng)前值,而done表示是否全部遍歷完成. - 那么迭代器一般是如何使用的呢?其實無論是數(shù)組,對象,集合或者是其他的數(shù)據(jù)結(jié)構(gòu),迭代器中都是提供了
next方法
,每次去調(diào)用這個next方法都會返回這個數(shù)據(jù)集合的下一個值
,聯(lián)想一下C語言中的''指針''移動,這也就解釋了為什么這里面要有一個next方法了. - 所以這部分代碼也就變的比較的好理解了,我們實現(xiàn)了了一個
Symbol.iterator
方法,然后在里面定義了索引index并獲取到了data數(shù)組,接著我們就return一個迭代器對象,里面包含next方法
,然后進(jìn)行判斷如果當(dāng)前索引小于數(shù)組長度,那么就返回一個對象里面包含此時的value值和done,并且done為false,表明此時迭代并沒有完成,否則就是最終返回一個done為true,表明此時迭代事件已經(jīng)完成。
經(jīng)過上面的處理大家也看到這樣做是非常麻煩的,如果我們不想要通過這種方式去獲取每一個值呢?那么我們只能來使用一些巧妙的手段來處理一下:我們要避免直接的去遍歷對象,而是要通過某種方法來進(jìn)行一個過渡的處理.
所以如果我們要使用for of來去迭代對象,那么我們只能通過一些手段來處理加工一下才可以
let sum = 0; let obj3 = {x: 1,y: 2, z: 3,}; for (const value of Object.values(obj3)) { ?sum += value; } console.log(Object.values(obj3));//[1,2,3] console.log(sum);//6
在這里面我們使用了Object.values
方法來獲取對象中的值,經(jīng)過處理之后返回一個數(shù)組,里面是包含對象中值的數(shù)組.而像數(shù)組,Map。Set,字符串,這都是內(nèi)置了迭代器的類型,因此可以使用for of來進(jìn)行迭代處理。當(dāng)然這里面我們還可以使用類似Object.entries()和Object.keys()等方法來處理,這里就不再展開.
接著說一下for in
在介紹完for of之后我們緊接著說一下for in
,for in
最直接的體現(xiàn)就是它可以直接的遍歷處理對象類型的數(shù)據(jù),不需要像for of那樣在給他增加一個迭代器屬性,下面我就來介紹一下:
let obj4 = { ?hobby: "唱,跳,rap", ?name: "kun", ?sex: "男", }; for (const key in obj4) { ?console.log("屬性名" + key, "屬性值" + obj4[key]); }
采用這種方式就不會出現(xiàn)報錯,可以正常的打印輸出值。因此如果我們在實際場景中使用的時候一般處理對象肯定是要使用for in來處理,但是像是如果遇到字符串,map等等這些本身帶有迭代器的類型我們就可以交給for of 來處理,具體場景具體說明。
同時這也應(yīng)證了上面所說的使用for in 中打印的是key值,因此我們要想獲取屬性值要通過obj4[key]。
同樣使用for in我們也可以處理類似像map,set,string等類型的數(shù)據(jù)。但是和for of 最顯著的區(qū)別還是我們可以直接處理對象.
總結(jié)
這里面我們解釋了為什么for of 不能用來處理普通的對象,以及如何去處理,并且介紹了每種方法適合用來解決的問題,因此我們在使用的時候要根據(jù)具體的場景來具體的分析處理.
到此這篇關(guān)于JavaScript中for of和for in的區(qū)別詳解的文章就介紹到這了,更多相關(guān)JavaScript for of和for in區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 全面解析JavaScript里的循環(huán)方法之forEach,for-in,for-of
- 詳解Js里的for…in和for…of的用法
- js遍歷詳解(forEach, map, for, for...in, for...of)
- js中forEach,for in,for of循環(huán)的用法示例小結(jié)
- js中for-in和for-of的區(qū)別詳解
- JavaScript 中for/of,for/in 的詳細(xì)介紹
- JS中for...in?和?for...of?的區(qū)別解析
- JavaScript中for-in和for-of的不同之處及如何正確使用
- JS中for,for...in,for...of和forEach的區(qū)別和用法實例
- JavaScript中for in和for of的區(qū)別示例詳解
相關(guān)文章
javascript+css3開發(fā)打氣球小游戲完整代碼
這是一個簡單但是印象深刻的小游戲,打氣球小游戲的實現(xiàn)代碼,主要基于js和css3,基于css3畫氣球,具體實現(xiàn)代碼大家參考下本文2017-11-11基于Express框架使用POST傳遞Form數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了基于Express框架使用POST傳遞Form數(shù)據(jù),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-08-08javascript innerHTML、outerHTML、innerText、outerText的區(qū)別
這篇文章主要介紹了javascript innerHTML、outerHTML、innerText、outerText的區(qū)別,本文講解了它們的功能、使用實例、和不同之處,需要的朋友可以參考下2008-11-11nuxt+axios實現(xiàn)打包后動態(tài)修改請求地址的方法
這篇文章主要介紹了nuxt+axios實現(xiàn)打包后動態(tài)修改請求地址的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04webpack教程之webpack.config.js配置文件
本篇文章主要介紹了webpack教程之webpack.config.js配置文件 ,具有一定的參考價值,有興趣的可以了解一席2017-07-07moment.js輕松實現(xiàn)獲取當(dāng)前日期是當(dāng)年的第幾周
這篇文章主要介紹了moment.js輕松實現(xiàn)獲取當(dāng)前日期是當(dāng)年的第幾周,需要的朋友可以參考下2015-02-02Easyui form combobox省市區(qū)三級聯(lián)動
這篇文章主要介紹了Easyui form combobox省市區(qū)三級聯(lián)動 的相關(guān)資料,需要的朋友可以參考下2016-01-01- 向?qū)Э梢宰屇愕木W(wǎng)站用戶快速上手使用你的web應(yīng)用,提高網(wǎng)站的吸引力。向?qū)б话惴譃楹脦讉€步驟,每個步驟收集一些數(shù)據(jù),并且支持退回功能,所有步驟完成后可以得到每一步的收集結(jié)果。這里給大家展示一種比較通用,靈活且簡單的向?qū)Э蚣堋?/div> 2011-08-08
最新評論