JavaScript中數組和對象不同遍歷方法的順序規則

在JavaScript中,不同遍歷方法的順序規則和適用場景存在顯著差異。以下是主要方法的遍歷順序總結:

一、數組遍歷方法

  1. for循環
    ? 嚴格按數組索引順序遍歷(0 → length-1)

    ? 支持breakcontinue中斷循環

    ? 性能最優,適合大規模數據

  2. forEach
    ? 按索引順序執行回調,但無法中途中斷循環

    ? 跳過空元素(稀疏數組)

    ? 典型場景:簡單遍歷且無需生成新數組

  3. map
    ? 順序與forEach一致,但會返回新數組(原數組不變)

    ? 需避免用map替代forEach(設計目的不同)

  4. for...of
    ? 按數組索引順序遍歷元素值

    ? 支持break中斷,可遍歷所有可迭代對象(如Set、Map)


二、對象遍歷方法

  1. for...in
    ? 順序不保證,遵循以下非標準規則:

    ? 數值鍵(如"2")升序排列

    ? 字符串鍵按插入順序排列

    ? 包含原型鏈的可枚舉屬性

    ? 適用場景:僅建議用于調試對象屬性

  2. Object.keys/Object.entries
    ? 返回自身可枚舉屬性,順序規則:

    ? 數值鍵升序排列

    ? 非數值鍵按插入順序

    ? 典型用法:Object.entries(obj).forEach(([key,val]) => ...)


三、特殊場景對比

方法適用類型順序保證中斷支持性能排序(快→慢)
for數組? 索引順序?最快
for...of可迭代對象? 元素順序?接近for
Object.keys對象數值鍵升序+插入順序?優于for...in
for...in對象/數組?(數值鍵特殊排序)?最慢

四、最佳實踐建議

  1. 數組遍歷優先用for(性能要求高)或for...of(簡潔性優先)
  2. 對象遍歷推薦Object.entries+解構,或轉為Map保證插入順序
  3. 避免用for...in遍歷數組(可能包含非索引屬性)
  4. 需要過濾/轉換數據時用map,僅需副作用操作時用forEach

在 JavaScript 中,for...inObject.keys() 的遍歷順序規則存在一定規律,但其確定性因數據類型和瀏覽器實現而異。以下是具體規則的綜合分析:


一、for...in 的遍歷順序規則

  1. 數值鍵(自然數)優先升序排列
    ? 若屬性名為可解析為 32 位無符號整數的字符串(如 "0""5"),會按數值大小升序排列。

    ? 示例:{ "2": "a", "1": "b" } → 輸出順序為 "1", "2"

  2. 非數值鍵按插入順序排列
    ? 字符串鍵(非自然數)和 Symbol 鍵按屬性添加的先后順序遍歷。

    ? 示例:{ a: 1, b: 2 } → 通常輸出 "a", "b"(但引擎優化可能導致例外)。

  3. 混合類型鍵的順序優先級
    ? 遍歷順序為:自然數鍵升序 → 字符串鍵插入順序 → Symbol 鍵插入順序。

    ? 示例:{ 3: "num", c: "str", [Symbol()]: "sym" } → 順序為 "3", "c", Symbol()


二、Object.keys() 的遍歷順序規則
Object.keys() 的返回順序與 for...in 完全一致,但有以下區別:

  1. 僅返回自身可枚舉屬性
    ? 不包含原型鏈上的屬性,而 for...in 可能遍歷到繼承屬性。

  2. 不包含 Symbol 屬性
    ? Symbol 鍵需通過 Object.getOwnPropertySymbols() 獲取。

  3. 過濾非可枚舉屬性
    ? Object.keys() 僅返回可枚舉屬性,而 for...in 可能受配置影響。


三、特殊場景與兼容性

  1. 舊版本瀏覽器差異
    ? ES6 前對象屬性順序無規范保證,現代瀏覽器(Chrome、Firefox 等)遵循上述規則,但 IE 等舊瀏覽器可能表現不同。

  2. 負數和浮點數的處理
    ? 如 "-5""2.5" 視為字符串鍵,按插入順序排列。

  3. 科學計數法鍵
    ? "1e3" 解析為 1000,視為自然數鍵。


四、最佳實踐建議

  1. 避免依賴順序的場景
    ? 若需嚴格順序,優先使用數組或 Map 類型。

  2. 強制排序方法
    ? 使用 Object.keys(obj).sort() 自定義順序。

    ? 示例:按字符串長度排序:

    const keys = Object.keys(obj).sort((a, b) => a.length - b.length);
    
  3. 檢查鍵類型的兼容性
    ? 自然數判斷:Number.isInteger(parseFloat(key)) && parseFloat(key) >= 0


總結對比表

方法數值鍵順序非數值鍵順序包含繼承屬性包含 Symbol
for...in升序插入順序??
Object.keys升序插入順序??

通過合理選擇遍歷方法并理解其底層規則,可有效規避因順序不確定性導致的邏輯錯誤。


在這里插入圖片描述
是的,for...inObject.keys() 均無法遍歷對象的 Symbol 類型屬性。這是由 JavaScript 語言特性決定的,具體原因及替代方法如下:


一、無法遍歷 Symbol 屬性的原因

  1. 語言設計規范
    ? Symbol 屬性默認不可枚舉:JavaScript 中 Symbol 類型的屬性不會被常規遍歷方法(如 for...inObject.keys())包含,這是語言規范的設計。

    ? 隱藏性與安全性:Symbol 的設計初衷是解決屬性命名沖突,并作為對象的“內部元數據”或私有屬性,避免被意外訪問或修改。

  2. 方法的功能限制
    ? for...in:遍歷對象自身及原型鏈上的可枚舉字符串鍵屬性,跳過 Symbol 鍵。

    ? Object.keys():僅返回對象自身的可枚舉字符串鍵屬性數組,同樣不包含 Symbol 鍵。


二、替代方法:遍歷 Symbol 屬性
若需操作 Symbol 屬性,可通過以下專用 API 實現:

  1. Object.getOwnPropertySymbols(obj)
    ? 返回對象自身所有 Symbol 鍵的數組,無論是否可枚舉。

    const obj = { [Symbol('key')]: 'value' };
    const symbols = Object.getOwnPropertySymbols(obj); // [Symbol(key)]
    
  2. Reflect.ownKeys(obj)
    ? 返回對象自身所有鍵的數組,包括 字符串鍵和 Symbol 鍵(無論是否可枚舉)。

    const obj = { a: 1, [Symbol('b')]: 2 };
    Reflect.ownKeys(obj); // ["a", Symbol(b)]
    

三、綜合對比表

方法/屬性遍歷 Symbol 鍵遍歷字符串鍵包含原型鏈屬性包含不可枚舉屬性
for...in????
Object.keys()????
Object.getOwnPropertySymbols()????
Reflect.ownKeys()????

四、使用場景建議
? 常規遍歷:若只需處理字符串鍵屬性,使用 for...inObject.keys() 即可。

? 處理 Symbol 屬性:優先選擇 Object.getOwnPropertySymbols()Reflect.ownKeys(),例如定義私有屬性或元數據時。

? 避免命名沖突:通過 Symbol 鍵隱藏關鍵屬性,提升代碼安全性。

完整示例及性能對比可參考 MDN Web 文檔。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/79968.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79968.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/79968.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

緩存(1):三級緩存

三級緩存是指什么 我們常說的三級緩存如下: CPU三級緩存Spring三級緩存應用架構(JVM、分布式緩存、db)三級緩存 CPU 基本概念 CPU 的訪問速度每 18 個月就會翻 倍,相當于每年增? 60% 左右,內存的速度當然也會不斷…

Android setContentView()源碼分析

文章目錄 Android setContentView()源碼分析前提setContentView() 源碼分析總結 Android setContentView()源碼分析 前提 Activity 的生命周期與 ActivityThread 相關,調用 startActivity() 時,會調用 ActivityThread#performLaunchActivity()&#xf…

uniapp自定義步驟條(可二開進行調試)

前言 有一個業務需求是需要一個步驟條&#xff0c;但是發現開源的都不太合適&#xff0c;所以就自己寫了一個。 開始 test.vue <template><view class"authenticateRecordDetails_container"><!-- 進度 --><view class"authenticateSte…

22、近端策略優化算法(PPO)論文筆記

近端策略優化算法&#xff08;PPO&#xff09;論文筆記 一、研究背景與目標二、**方法****3.1 策略梯度基礎****3.2 信任區域方法&#xff08;TRPO&#xff09;****3.3 剪切代理目標函數&#xff08;LCLIP&#xff09;****3.4 自適應KL懲罰系數****3.5 算法實現** 三、 L CLIP…

web 自動化之 Selenium 元素定位和瀏覽器操作

文章目錄 一、元素定位的八大方法1、基于 id/name/class/tag_name 定位2、基于 a 標簽元素的鏈接文本定位3、基于xpath定位4、css定位 二、瀏覽器操作1、信息獲取2、 瀏覽器關閉3、 瀏覽器控制 一、元素定位的八大方法 web 自動化測試就是通過代碼對網頁進行測試&#xff0c;在…

前端面經 作用域和作用域鏈

含義&#xff1a;JS中變量生效的區域 分類&#xff1a;全局作用域 或者 局部作用域 局部作用域&#xff1a;函數作用域 和 塊級作用域ES6 全局作用域:在代碼中任何地方都生效 函數中定義函數中生效&#xff0c;函數結束失效 塊級作用域 使用let或const 聲明 作用域鏈:JS查…

【C/C++】RPC與線程間通信:高效設計的關鍵選擇

文章目錄 RPC與線程間通信&#xff1a;高效設計的關鍵選擇1 RPC 的核心用途2 線程間通信的常規方法3 RPC 用于線程間通信的潛在意義4 主要缺點與限制4.1 缺點列表4.2 展開 5 替代方案6 結論 RPC與線程間通信&#xff1a;高效設計的關鍵選擇 在C或分布式系統設計中&#xff0c;…

兩種方法求解最長公共子序列問題并輸出所有解

最長公共子序列&#xff08;Longest Common Subsequence, LCS&#xff09;是動態規劃領域的經典問題&#xff0c;廣泛應用于生物信息學&#xff08;如DNA序列比對&#xff09;、文本差異比對&#xff08;如Git版本控制&#xff09;等領域。本文將通過??自頂向下遞歸記憶化??…

SpringBoot應急知識學習系統開發實現

概述 一個基于SpringBoot開發的應急知識學習系統&#xff0c;該系統提供了完整的用戶注冊、登錄、知識學習與測評功能。對于開發者而言&#xff0c;這是一個值得參考的免費Java源碼項目&#xff0c;可以幫助您快速構建類似的教育平臺。 主要內容 5.2 注冊模塊的實現 系統采…

【Python 字符串】

Python 中的字符串&#xff08;str&#xff09;是用于處理文本數據的基礎類型&#xff0c;具有不可變性、豐富的內置方法和靈活的操作方式。以下是 Python 字符串的核心知識點&#xff1a; 一、基礎特性 定義方式&#xff1a; s1 單引號字符串 s2 "雙引號字符串" s…

第十六屆藍橋杯大賽軟件賽C/C++大學B組部分題解

第十六屆藍橋杯大賽軟件賽C/C大學B組題解 試題A: 移動距離 問題描述 小明初始在二維平面的原點&#xff0c;他想前往坐標(233,666)。在移動過程中&#xff0c;他只能采用以下兩種移動方式&#xff0c;并且這兩種移動方式可以交替、不限次數地使用&#xff1a; 水平向右移動…

如何使用極狐GitLab 軟件包倉庫功能托管 npm?

極狐GitLab 是 GitLab 在中國的發行版&#xff0c;關于中文參考文檔和資料有&#xff1a; 極狐GitLab 中文文檔極狐GitLab 中文論壇極狐GitLab 官網 軟件包庫中的 npm 包 (BASIC ALL) npm 是 JavaScript 和 Node.js 的默認包管理器。開發者使用 npm 共享和重用代碼&#xff…

Matlab 基于Hough變換的人眼虹膜定位方法

1、內容簡介 Matlab220-基于Hough變換的人眼虹膜定位方法 可以交流、咨詢、答疑 2、內容說明 略 3、仿真分析 略 4、參考論文 略

chili調試筆記14 畫線 頁面布置 線條導出dxf

2025-05-08 09-05-06 llm畫線 頁面布置 expand有自己的格式 刪了就會按照子元素格式 不加px無效 沒有指定尺寸設置100%無效 怎么把線條導出dxf command({name: "file.export",display: "command.export",icon: "icon-export", }) export class…

藍綠發布與金絲雀發布

藍綠發布與金絲雀發布 一、藍綠發布&#xff1a;像「搬家」一樣安全上線1. 生活化故事2. 技術步驟拆解步驟①&#xff1a;初始狀態步驟②&#xff1a;部署新版本到綠環境步驟③&#xff1a;內部驗證綠環境步驟④&#xff1a;一鍵切換流量步驟⑤&#xff1a;監控與回滾 3. 藍綠發…

【2025五一數學建模競賽B題】 礦山數據處理問題|建模過程+完整代碼論文全解全析

你是否在尋找數學建模比賽的突破點&#xff1f;數學建模進階思路&#xff01; 作為經驗豐富的美賽O獎、國賽國一的數學建模團隊&#xff0c;我們將為你帶來本次數學建模競賽的全面解析。這個解決方案包不僅包括完整的代碼實現&#xff0c;還有詳盡的建模過程和解析&#xff0c…

JavaSE核心知識點02面向對象編程02-02(封裝、繼承、多態)

&#x1f91f;致敬讀者 &#x1f7e9;感謝閱讀&#x1f7e6;笑口常開&#x1f7ea;生日快樂?早點睡覺 &#x1f4d8;博主相關 &#x1f7e7;博主信息&#x1f7e8;博客首頁&#x1f7eb;專欄推薦&#x1f7e5;活動信息 文章目錄 JavaSE核心知識點02面向對象編程02-02&#…

Yolo遷移訓練-帶訓練源碼

目錄 下載Git 拉下yolo模型 下載labelimg 準備訓練集 遷移訓練 繼續訓練 下載Git Git - Downloading Package 拉下yolo模型 然后用克隆腳本拉下yolo模型 python clone_yolo.py import os import subprocess import sys import shutildef check_git_installed():"…

LangChain框架-PromptTemplate 詳解

摘要 本文聚焦于 LangChain 框架中PromptTemplate提示詞模板模塊的深度解析,主要參考langchain_core.prompts源碼模塊與官方文檔。系統梳理 LangChain 對提示詞模板的封裝邏輯與設計思路,旨在幫助讀者構建全面、深入的知識體系,為高效運用LangChain 框架的提示詞模板開發應用…

中小企業設備預測性維護三步構建法:從零到精的技術躍遷與中訊燭龍實踐

在工業4.0浪潮中&#xff0c;中小企業常陷入"設備故障頻發"與"數字化成本高企"的雙重困境。本文基于半導體、食品加工等行業實證數據&#xff0c;結合中訊燭龍系統技術突破&#xff0c;為中小企業提供一套零基礎、低門檻、可擴展的預測性維護實施框架&…