JavaScript中遍歷對象的6種方式總結(jié)
在日常的前端開發(fā)中,我們經(jīng)常需要處理和操作 JavaScript 對象。無論是從接口獲取的數(shù)據(jù)解析,還是狀態(tài)管理中的數(shù)據(jù)重組,遍歷對象都是一個(gè)高頻且基礎(chǔ)的操作。
然而,很多人只知道 for...in,卻忽略了其他更現(xiàn)代、更高效的遍歷方式。本文將系統(tǒng)梳理 JavaScript 中遍歷對象的 6 種方法,并結(jié)合實(shí)際場景告訴你:什么時(shí)候該用哪種方式?它們的區(qū)別是什么?如何避免常見坑?
一、為什么遍歷對象這么重要?
對象是 JavaScript 的核心數(shù)據(jù)類型之一。在 Vue、React、Redux、Axios 等框架和庫中,對象無處不在:
- 接口返回的 JSON 數(shù)據(jù)
- 表單字段映射
- 配置項(xiàng)動(dòng)態(tài)處理
- 國際化語言包
- 緩存鍵值存儲(chǔ)
掌握正確的遍歷方式,不僅能提升代碼可讀性,還能避免性能問題和邏輯錯(cuò)誤。
二、6 種遍歷對象的方法詳解
1. for...in 循環(huán) —— 最基礎(chǔ)但需謹(jǐn)慎使用
const user = { name: 'Alice', age: 25, city: 'Beijing' };
for (let key in user) {
console.log(key, user[key]);
}優(yōu)點(diǎn):
- 兼容性好,支持老瀏覽器
- 可以遍歷原型鏈上的可枚舉屬性(有時(shí)是優(yōu)勢)
缺點(diǎn)與風(fēng)險(xiǎn):
- 會(huì)遍歷到繼承的可枚舉屬性,可能導(dǎo)致意外輸出
- 如果不加
hasOwnProperty判斷,容易出 bug
安全寫法:
for (let key in user) {
if (user.hasOwnProperty(key)) {
console.log(key, user[key]);
}
}適用場景:需要檢查原型鏈屬性的特殊情況(極少),否則不推薦作為首選。
2. Object.keys() —— 獲取所有自身可枚舉鍵
Object.keys(user).forEach(key => {
console.log(key, user[key]);
});優(yōu)點(diǎn):
- 只返回對象自身的可枚舉屬性
- 返回?cái)?shù)組,可鏈?zhǔn)秸{(diào)用
.map()、.filter()等 - 是現(xiàn)代開發(fā)中最常用的遍歷方式之一
適用場景:你想“像數(shù)組一樣”操作對象的鍵,比如篩選、轉(zhuǎn)換等。
3. Object.values() —— 只關(guān)心值的時(shí)候用它
console.log(Object.values(user));
// ['Alice', 25, 'Beijing']
Object.values(user).forEach(value => {
console.log(value);
});優(yōu)點(diǎn):直接獲取所有值,無需再通過 obj[key] 提取
適用場景:統(tǒng)計(jì)數(shù)值總和、批量處理值、導(dǎo)出為數(shù)組等。
4. Object.entries() 強(qiáng)烈推薦:獲取鍵值對
這是 ES2017 引入的強(qiáng)大方法,返回 [key, value] 數(shù)組。
Object.entries(user).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});高級(jí)用法 1:轉(zhuǎn)為 Map
const map = new Map(Object.entries(user));
console.log(map.get('name')); // 'Alice'高級(jí)用法 2:過濾并重建對象
const filtered = Object.fromEntries(
Object.entries(user).filter(([key, value]) => typeof value === 'string')
);
// { name: 'Alice', city: 'Beijing' }適用場景:需要同時(shí)處理鍵和值、對象轉(zhuǎn)換、動(dòng)態(tài)重構(gòu)等。這是現(xiàn)代 JS 開發(fā)的首選方式!
5. Object.getOwnPropertyNames() —— 包含不可枚舉屬性
有些屬性是“隱藏”的,比如通過 Object.defineProperty 定義的不可枚舉屬性。
const obj = { a: 1 };
Object.defineProperty(obj, 'b', {
value: 2,
enumerable: false
});
console.log(Object.keys(obj)); // ['a']
console.log(Object.getOwnPropertyNames(obj)); // ['a', 'b']適用場景:深拷貝、元編程、屬性復(fù)制等需要完整元信息的場景。
6. Reflect.ownKeys() —— 最全的遍歷方式
它能拿到:
- 所有字符串鍵
- 所有 Symbol 鍵
- 可枚舉和不可枚舉屬性
const sym = Symbol('id');
const obj = { name: 'Bob' };
obj[sym] = 100;
console.log(Reflect.ownKeys(obj)); // ['name', Symbol(id)]適用場景:編寫庫、框架、深拷貝工具時(shí),確保不遺漏任何屬性。
三、對比總結(jié):該怎么選?
| 方法 | 是否包含繼承 | 是否包含不可枚舉 | 是否包含 Symbol | 返回類型 | 推薦指數(shù) |
|---|---|---|---|---|---|
for...in | ? 是 | ? 否 | ? 否 | - | ??☆ |
Object.keys() | ? 否 | ? 否 | ? 否 | 字符串?dāng)?shù)組 | ???? |
Object.values() | ? 否 | ? 否 | ? 否 | 值數(shù)組 | ???? |
Object.entries() | ? 否 | ? 否 | ? 否 | [k,v] 數(shù)組 | ????? |
getOwnPropertyNames | ? 否 | ? 是 | ? 否 | 字符串?dāng)?shù)組 | ???☆ |
Reflect.ownKeys() | ? 否 | ? 是 | ? 是 | 所有鍵數(shù)組 | ???? |
結(jié)論:90% 的場景推薦使用 Object.entries(),語義清晰、功能強(qiáng)大、兼容現(xiàn)代開發(fā)需求。
四、實(shí)戰(zhàn)技巧 & 常見誤區(qū)
誤區(qū) 1:直接 JSON.stringify(Map) 或 JSON.stringify(Symbol)
const obj = { [Symbol('x')]: 1 };
console.log(JSON.stringify(obj)); // {} —— Symbol 被忽略!解決方案:使用 Reflect.ownKeys() 處理 Symbol。
誤區(qū) 2:認(rèn)為 for...in 和 Object.keys() 一樣
function Person() {}
Person.prototype.say = function() {};
const p = new Person();
p.name = 'Tom';
console.log(Object.keys(p)); // ['name']
for (let k in p) console.log(k); // name, say(包括原型方法?。?/pre>建議:除非特殊需求,優(yōu)先使用 Object.keys() 或 entries()。
技巧:快速轉(zhuǎn)換對象結(jié)構(gòu)
// 將 { id1: '張三', id2: '李四' } 轉(zhuǎn)為數(shù)組
const users = Object.entries(obj).map(([id, name]) => ({ id, name }));五、結(jié)語
遍歷對象看似簡單,實(shí)則暗藏玄機(jī)。選擇合適的遍歷方式,不僅能讓你的代碼更健壯,還能提升開發(fā)效率和可維護(hù)性。
記住一句話:“能用 Object.entries() 的地方,就不要用 for...in。”
隨著 ES6+ 的普及,Object.keys/values/entries 已成為現(xiàn)代 JavaScript 的標(biāo)準(zhǔn)實(shí)踐。掌握它們,是你邁向高級(jí)前端開發(fā)者的重要一步。
以上就是JavaScript中遍歷對象的6種方式總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript遍歷對象的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于JS實(shí)現(xiàn)移動(dòng)端訪問PC端頁面時(shí)跳轉(zhuǎn)到對應(yīng)的移動(dòng)端網(wǎng)頁
不想通過CSS自適應(yīng)在PC端和移動(dòng)端分別顯示不同的樣式,那么只能通過在移動(dòng)端訪問PC端網(wǎng)頁時(shí)跳轉(zhuǎn)到對應(yīng)的移動(dòng)端網(wǎng)頁了,那么怎么跳轉(zhuǎn)呢,網(wǎng)上也有很多文章說明,以下實(shí)現(xiàn)思路經(jīng)過小編測試過,需要的朋友可以參考下2016-04-04
JavaScript中Form表單技術(shù)匯總(推薦)
這篇文章主要介紹了JavaScript中Form表單技術(shù)的相關(guān)資料,包括簡單的表單驗(yàn)證和正則表達(dá)式驗(yàn)證,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06
JavaScript設(shè)計(jì)模式之職責(zé)鏈模式應(yīng)用示例
這篇文章主要介紹了JavaScript設(shè)計(jì)模式之職責(zé)鏈模式,結(jié)合實(shí)例形式分析了javascript責(zé)任鏈模式的概念、原理、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2018-08-08
CocosCreator入門教程之網(wǎng)絡(luò)通信
這篇文章主要介紹了CocosCreator的網(wǎng)絡(luò)通信,內(nèi)容不多,涉及到的細(xì)節(jié),讀者可以根據(jù)實(shí)際情況,自己去延申2021-04-04
JS創(chuàng)建自定義表格具體實(shí)現(xiàn)
創(chuàng)建自定義表格的方法有很多,本文為大家介紹下使用js是如何創(chuàng)建的,感興趣的朋友可以參考下2014-02-02
JS實(shí)現(xiàn)html頁面點(diǎn)擊下載文件的兩種方式
這篇文章主要介紹了JS實(shí)現(xiàn)html頁面點(diǎn)擊下載文件的兩種方式,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07

