記錄--for in 和 for of的區別詳解以及為for in的輸出順序

来源:https://www.cnblogs.com/smileZAZ/archive/2022/11/02/16851578.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 for in 和 for of 相對於大家肯定都不陌生,都是用來遍歷屬性的沒錯。那麼先看下麵的一個例子: 例1 const obj = { a: 1, b: 2, c: 3 } for (let i in obj) { console.l ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

for in 和 for of 相對於大家肯定都不陌生,都是用來遍歷屬性的沒錯。那麼先看下麵的一個例子:

例1

const obj = {
        a: 1,
        b: 2,
        c: 3
    }
    for (let i in obj) {
        console.log(i)
        // a
        // b
        // c
    }
    for (let i of obj) {
        console.log(i)
        // Uncaught TypeError: obj is not iterable 報錯了
    }

以上代碼通過 for in 和 for of 對一個obj對象進行遍歷,for in 正常的獲取了對象的 key值,分別列印 a、b、c,而 for of卻報錯了。

例2:

以上是遍歷對象,下麵再看一個遍曆數組的例子。

    const arr = ['a', 'b', 'c']
    // for in 迴圈
    for (let i in arr) {
        console.log(i)
        // 0
        // 1
        // 2
    }
    
    // for of
    for (let i of arr) {
        console.log(i)
        // a
        // b
        // c
    }

以上代碼是對一個數組進行遍歷, for in 返回的值為 0、1、2,這不是數組的下標嗎? 而 for of 返回的是 a、b、c,這一次沒有報錯,為什麼呢?

例3

    const arr = ['a', 'b']
    // 手動給 arr數組添加一個屬性
    arr.name = 'qiqingfu'
    
    // for in 迴圈可以遍歷出 name 這個鍵名
    for (let i in arr) {
        console.log(i)
        // a
        // b
        // name
    }

for in 的特點

結合上面的兩個例子,分析得出:

  • for ... in 迴圈返回的值都是數據結構的 鍵值名。

  • 遍歷對象返回的對象的key值,遍曆數組返回的數組的下標(key)。

  • for ... in 迴圈不僅可以遍曆數字鍵名,還會遍歷原型上的值和手動添加的其他鍵。如——例3

  • 特別情況下, for ... in 迴圈會以看起來任意的順序遍歷鍵名

(為什麼說看起來,其實也是有規律的,這個就要扯到 常規屬性和 排序屬性,想深入學習的可以看讀李老課程引發的思考之JS設計思想篇

這裡可以簡單說一下

1.什麼是對象中的 常規屬性和 排序屬性

function Foo() {
  this[100] = 'test-100'
  this[1] = 'test-1'
  this["B"] = 'bar-B'
  this[50] = 'test-50'
  this[9] = 'test-9'
  this[8] = 'test-8'
  this[3] = 'test-3'
  this[5] = 'test-5'
  this["A"] = 'bar-A'
  this["C"] = 'bar-C'
}
var bar = new Foo()
for(key in bar){
  console.log(`index:${key} value:${bar[key]}`)
}

在上⾯這段代碼中,我們利⽤構造函數Foo創建了⼀個bar對象,在構造函數中,我們給bar對象設置了很多 屬性,包括了數字屬性和字元串屬性,然後我們枚舉出來了bar對象中所有的屬性,並將其⼀⼀列印出來, 下⾯就是執⾏這段代碼所列印出來的結果

index:1 value:test-1
index:3 value:test-3
index:5 value:test-5
index:8 value:test-8
index:9 value:test-9
index:50 value:test-50
index:100 value:test-100
index:B value:bar-B
index:A value:bar-A
index:C value:bar-C

觀察這段列印出來的數據,我們發現列印出來的屬性順序並不是我們設置的順序,我們設置屬性的時候是亂 序設置的,⽐如開始先設置100,然後有設置了1,但是輸出的內容卻⾮常規律,總的來說體現在以下兩 點:

設置的數字屬性被最先列印出來了,並且按照數字⼤⼩的順序列印的;

設置的字元串屬性依然是按照之前的設置順序列印的,⽐如我們是按照B、A、C的順序設置的,列印出來,依然是這個順序。

之所以出現這樣的結果,是因為在ECMAScript規範中定義了 「數字屬性應該按照索引值⼤⼩升序排列,字元 串屬性根據創建時的順序升序排列。」在這⾥我們把對象中的數字屬性稱為 「排序屬性」,在V8中被稱為 elements,字元串屬性就被稱為 「常規屬性」, 在V8中被稱為 properties。在V8內部,為了有效地提升存儲和訪問這兩種屬性的性能,分別使⽤了兩個 線性數據結構來分別保存排序 屬性和常規屬性,具體結構如下圖所⽰:

在elements對象中,會按照順序存放排序屬性,properties屬性則指向了properties對 象,在properties對象中,會按照創建時的順序保存了常規屬性。

總結一句: for in 迴圈特別適合遍歷對象。

for of 特點

for of 迴圈用來獲取一對鍵值對中的值,而 for in 獲取的是 鍵名

一個數據結構只要部署了 Symbol.iterator 屬性, 就被視為具有 iterator介面, 就可以使用 for of迴圈。

例1這個對象,沒有 Symbol.iterator這個屬性,所以使用 for of會報 obj is not iterable

for of 不同與 forEach, 它可以與 break、continue和return 配合使用,也就是說 for of 迴圈可以隨時退出迴圈。

提供了遍歷所有數據結構的統一介面

哪些數據結構部署了 Symbol.iteratoer屬性了呢?

只要有 iterator 介面的數據結構,都可以使用 for of迴圈。

  • 數組 Array

  • Map

  • Set

  • String

  • arguments對象

  • Nodelist對象, 就是獲取的dom列表集合

-以上這些都可以直接使用 for of 迴圈。 凡是部署了 iterator 介面的數據結構也都可以使用數組的 擴展運算符(...)、和解構賦值等操作。

我也想讓對象可以使用 for of迴圈怎麼辦?使用 Object.keys() 獲取對象的 key值集合後,再使用 for of

以例1為例

 const obj = {
        a: 1,
        b: 2,
        c: 3
    }

    for (let i of Object.keys(obj)) {
        console.log(i)
        // 1
        // 2
        // 3
    }

也可以給一個對象部署 Symbol.iterator屬性。

本文轉載於:

https://juejin.cn/post/6854573212039151629

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 先說點廢話 最近在實際業務中,需要編寫一個方法根據數組中每一個對象的一個相同欄位,來將該欄位值相等的對象重新編入一個數組,返回一個嵌套的數組對象,特地來做個總結。 當然需要註意的是,在開發過程這種數組的處理函數,應當被編寫到項目的公共工具函數庫中全局調用 目標對象數組 let dataArr = [ ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 一、概述 在我們開發中,經常要用到Vue.extend創建出Vue的子類來構造函數,通過new 得到子類的實例,然後通過$mount掛載到節點,如代碼: <div id="mount-point"></div> <!-- 創建構造器 -- ...
  • 1 yyg-cli 是什麼 yyg-cli 是優雅哥開發的快速創建 vue3 項目的腳手架。在 npm 上發佈了兩個月,11月1日進行了大升級,發佈 1.1.0 版本:支持創建 vue3 全家桶項目和 vue3 組件庫項目。具體如下: vue3 全家桶項目 使用 yyg-cli 創建的 vue3 全 ...
  • 邏輯導航 1.當在前端輸入用戶名和密碼之後,點擊登錄,後端校驗完畢返回前端 2.前端拿到需要首先做個判斷,判斷用戶是否輸入用戶名和密碼,未輸入則發出提示;輸入了則發送post請求給後端,校驗用戶名和密碼 3.校驗通過,前端拿到後端返回的token和用戶名等數據 4.登錄成功,則關閉登錄框,同時,在登 ...
  • 大部分同學都用過 CSS 的屏幕寬度媒體查詢,像是這樣: @media screen and (min-width: 900px) { div { padding: 1rem 3rem; } } 這裡表示的是與屏幕寬度相關的樣式設置,上面的代碼表示當屏幕寬度大於 900px 時,內部的樣式代碼塊才能 ...
  • 邏輯導航 1.當點擊頁面主頁的登錄/註冊按鈕時,彈出登錄/註冊模態框 2.登錄/註冊模態框也是一個小組件,在組件文件夾內創建對應組件 3.然後需要將該組件傳到header(頭部)組件內(進行相關的導入和註冊) 4. 補充子傳父組件語法 在子組件內 當點擊子組件里的東西時,傳遞給父組件一個事件,父組件 ...
  • 本文主要記錄 Vue.js 中的 Vuex,Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。 ...
  • 當我們使用vuex的時候,時不時能看到“更改Vuex中的store中的狀態唯一辦法就是提交mutations”,但是有沒有試想過,我們不提交mutations其實也能修改state的值?答案是可以的 我們可以直接使用如下方式; this.$store.state.num=666; 其中,這樣修改的話 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...