JS遍歷對象的幾種方法

来源:https://www.cnblogs.com/xyzhanjiang/archive/2020/06/16/13140455.html
-Advertisement-
Play Games

幾天前一個小伙伴問我 Object.getOwnPropertyNames() 是乾什麼用的 平時還真沒有使用到這個方法,一時不知如何回答 從方法名稱來分析,應該是返回的是對象自身屬性名組成的數組 那和 Object.keys() 方法不就一樣了嗎 感覺事情並不這麼簡單,於是我仔細看了一下這幾種遍歷 ...


幾天前一個小伙伴問我 Object.getOwnPropertyNames() 是乾什麼用的

平時還真沒有使用到這個方法,一時不知如何回答

從方法名稱來分析,應該是返回的是對象自身屬性名組成的數組

那和 Object.keys() 方法不就一樣了嗎

感覺事情並不這麼簡單,於是我仔細看了一下這幾種遍歷對象的方法的區別

for in

for in 迴圈是最基礎的遍歷對象的方式,它還會得到對象原型鏈上的屬性

// 創建一個對象並指定其原型,bar 為原型上的屬性
const obj = Object.create({
  bar: 'bar'
})

// foo 為對象自身的屬性
obj.foo = 'foo'

for (let key in obj) {
  console.log(obj[key]) // foo, bar
}

可以看到對象原型上的屬性也被迴圈出來了

在這種情況下可以使用對象的 hasOwnProperty() 方法過濾掉原型鏈上的屬性

for (let key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(obj[key]) // foo
  }
}

這時候原型上的 bar 屬性就被過濾掉了

Object.keys

Object.keys() 是 ES5 新增的一個對象方法,該方法返回對象自身屬性名組成的數組,它會自動過濾掉原型鏈上的屬性,然後可以通過數組的 forEach() 方法來遍歷

Object.keys(obj).forEach((key) => {
  console.log(obj[key]) // foo
})

另外還有 Object.values() 方法和 Object.entries() 方法,這兩方法的作用範圍和 Object.keys() 方法類似,因此不再說明

for in 迴圈和 Object.keys() 方法都不會返回對象的不可枚舉屬性

如果需要遍歷不可枚舉的屬性,就要用到前面提到的 Object.getOwnPropertyNames() 方法了

Object.getOwnPropertyNames

Object.getOwnPropertyNames() 也是 ES5 新增的一個對象方法,該方法返回對象自身屬性名組成的數組,包括不可枚舉的屬性,也可以通過數組的 forEach 方法來遍歷

// 創建一個對象並指定其原型,bar 為原型上的屬性
// baz 為對象自身的屬性並且不可枚舉
const obj = Object.create({
  bar: 'bar'
}, {
  baz: {
    value: 'baz',
    enumerable: false
  }
})

obj.foo = 'foo'

// 不包括不可枚舉的 baz 屬性
Object.keys(obj).forEach((key) => {
  console.log(obj[key]) // foo
})

// 包括不可枚舉的 baz 屬性
Object.getOwnPropertyNames(obj).forEach((key) => {
  console.log(obj[key]) // baz, foo
})

ES2015 新增了 Symbol 數據類型,該類型可以作為對象的鍵,針對該類型 ES2015 同樣新增了 Object.getOwnPropertySymbols() 方法

Object.getOwnPropertySymbols

Object.getOwnPropertySymbols() 方法返回對象自身的 Symbol 屬性組成的數組,不包括字元串屬性

Object.getOwnPropertySymbols(obj).forEach((key) => {
  console.log(obj[key])
})

什麼都沒有,因為該對象還沒有 Symbol 屬性

// 給對象添加一個不可枚舉的 Symbol 屬性
Object.defineProperties(obj, {
  [Symbol('baz')]: {
    value: 'Symbol baz',
    enumerable: false
  }
})

// 給對象添加一個可枚舉的 Symbol 屬性
obj[Symbol('foo')] = 'Symbol foo'

Object.getOwnPropertySymbols(obj).forEach((key) => {
  console.log(obj[key]) // Symbol baz, Symbol foo
})

Reflect.ownKeys

Reflect.ownKeys() 方法是 ES2015 新增的靜態方法,該方法返回對象自身所有屬性名組成的數組,包括不可枚舉的屬性和 Symbol 屬性

Reflect.ownKeys(obj).forEach((key) => {
  console.log(obj[key]) // baz, foo, Symbol baz, Symbol foo
})

對比

方式 基本屬性 原型鏈 不可枚舉 Symbol
for in
Object.keys()
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Reflect.ownKeys()

結論

這其中只有 for in 迴圈會得到對象原型鏈上的屬性,其它方法都只適用於對象自身的屬性

ES 語言後續添加的新特性不會對以前的代碼產生副作用,比如在 ES2015 之前就存在的 for in 迴圈,Object.keys() 和 Object.getOwnPropertyNames() 是肯定不會返回 Symbol 屬性的


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

-Advertisement-
Play Games
更多相關文章
  • 1 下載node.js 下載地址:https://nodejs.org/zh-cn/download/ 選擇對應系統的安裝包進行下載,本次安裝得是windows 64位系統(32位下載中會有一個X86這表示系統架構的意思。) 2 安裝Node.js 找到下載的安裝包,點擊進行安裝。 上面四個選項的意 ...
  • 平時用this有些混亂,所以寫個總結。 沒有箭頭函數之前,我們說this就是函數運行時所在的環境對象,但是在箭頭函數中this就是定義時所在的對象,先說大家熟知的:函數運行時所在的環境對象。 1、作為函數調用,this指向全局對象 2、作為對象的方法調用,該對象即為調用上下文,this指向該對象。 ...
  • iview DatePicker daterange data month UTC格式化問題 ...
  • npm install 裝包時提示Error EACCES permission denied解決辦法 ...
  • 1 <div class="pie" style="width:500px;height:500px;"></div> 2 3 <div class="line" style="width:500px;height:500px;"></div> 4 5 <script type="text/java ...
  • layui 是什麼? 是一個ui庫 UI設計(或稱界面設計)是指對軟體的人機交互、操作邏輯、界面美觀的整體設計。UI設計分為實體UI和虛擬UI,互聯網常用的UI設計是虛擬UI,UI即User Interface(用戶界面)的簡稱。 大致內容 觀察layui文件內的內部結構 ├─css //css目錄 ...
  • 前端早早聊大會,前端成長的新起點,與掘金聯合舉辦。 本文 是前端早早聊的第 45 位講師 ,也是第六屆 - Serverless 專場,來自閑魚前端團隊的丹俠的分享 - 講稿簡要整理版(完整版含演示請看錄播視頻和 PPT): 概述 今天給大家分享一下閑魚如何在現有產品中落地 FaaS,希望我們的實踐 ...
  • readyState document.readyState 返回當前文檔的狀態 屬性如下: uninitialized 還未開始載入 loading 載入中 interactive 已載入,文檔與用戶可以開始交互 complete 載入完成 DOMContentLoaded 當 DOMConten ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...