

统一声明:
1.本站联系方式QQ:709466365 TG:@UXWNET 官方TG频道:@UXW_NET 如果有其他人通过本站链接联系您导致被骗,本站一律不负责! 2.需要付费搭建请联系站长QQ:709466365 TG:@UXWNET 3.免实名域名注册购买- 游侠云域名 4.免实名国外服务器购买- 游侠网云服务
最常用的3种遍历方法:从基础到进阶,直接抄代码
遍历Object的键值对,其实就那么几种常用方法,但选对了能省很多麻烦。我把自己日常用得最多的3种方法整理出来,每一种都附了“直接能用的代码”和“要避开的坑”,你直接抄就行。
for...in
:最基础但要防“脏数据”for...in
应该是大家最早接触的遍历方法,它会循环对象的所有可枚举属性(包括原型链上的)。但正因为能遍历原型链,很容易拿到“不该拿的东西”——比如我之前写用户信息展示组件时,用for...in
遍历用户对象,结果把父类的“id”属性也读出来了,导致页面上显示两个“ID”字段,用户以为系统出问题了。
后来我学会了加hasOwnProperty
判断,只遍历对象自身的属性,代码立刻变干净:
const user = { name: '张三', age: 28 };
for (let key in user) {
// 关键:过滤原型链上的属性
if (user.hasOwnProperty(key)) {
console.log(键:${key},值:${user[key]}
);
}
}
这里要插个知识点:hasOwnProperty
是Object.prototype
的方法,用来判断属性是不是对象“自己的”,不是从原型链继承的。MDN文档里明确说过,“for...in
循环会遍历对象自身及其原型链上的可枚举属性”(参考链接:MDN for…in)。所以用for...in
一定要加hasOwnProperty
,不然很容易踩坑。
Object.keys/values/entries
:精准获取键值对如果不想处理原型链的问题,直接用Object
家族的这三个方法更省心——它们只遍历对象自身的可枚举属性,不用写过滤代码。我现在做商品列表、用户信息这些组件时,基本都用这三个方法,比for...in
少写3行代码,还没出过错。
Object.keys
:返回对象自身所有可枚举属性的键数组,适合只需要键的场景,比如渲染表头:const product = { id: 1, name: '手机', price: 3999 };
Object.values// 用Object.keys拿到所有键,遍历渲染表头
Object.keys(product).forEach(key => {
console.log(
表头:${key}
);});
:返回对象自身所有可枚举属性的值数组,适合只需要值的场景,比如统计商品总价:
javascript
总价:${total}元const cart = { apple: 20, banana: 15 };
// 计算购物车总价
const total = Object.values(cart).reduce((sum, price) => sum + price, 0);
console.log(
);
Object.entries
:返回对象自身所有可枚举属性的键值对数组,直接解构就能拿到键和值,我最常用这个写循环渲染:
javascript
${key}:${value}const order = { id: '20240501', goods: '耳机', amount: 1 };
// 遍历键值对,渲染订单详情
Object.entries(order).forEach(([key, value]) => {
console.log(
);
});
Reflect.ownKeys
:连Symbol键也不放过
Object.keys如果你的对象里有Symbol类型的键(比如用Symbol做唯一标识),普通方法是拿不到的——我之前就栽过这个坑:给对象加了个Symbol类型的“id”,结果用
遍历不到,导致统计功能少了一半数据。后来查文档才知道,Symbol键是“隐藏”的,要用到
Reflect.ownKeys。
Reflect.ownKeys会返回对象自身的所有属性,包括:
Object.defineProperty普通字符串键; Symbol类型键; 不可枚举属性(比如用 定义的)。
举个例子:
javascript
// 定义一个Symbol键
const symId = Symbol(‘uniqueId’);
const user = {
[symId]: ‘123456’, // Symbol键
name: ‘王五’,
age: 30
};
// 用Reflect.ownKeys拿到所有键
console.log(Reflect.ownKeys(user)); // 输出:[Symbol(uniqueId), ‘name’, ‘age’]
// 遍历所有键值对
Reflect.ownKeys(user).forEach(key => {
console.log(键:${key.toString()},值:${user[key]});
});
为了让你更清楚这三种方法的区别,我做了个对比表格,直接看就能选对方法:
Object.defineProperty
方法 特点 适用场景 是否需过滤原型链 for...in 遍历自身+原型链的可枚举属性 需要遍历所有可枚举属性时 是 Object.keys/values/entries 仅遍历自身的可枚举属性 精准获取自身键/值/键值对 否 Reflect.ownKeys 遍历自身所有属性(含Symbol、不可枚举) 需要完整获取所有属性时 否 踩过的3个坑:别让“小细节”毁了你的代码
我之前写遍历代码时,总觉得“语法对了就行”,结果踩了很多“小细节”的坑——比如可枚举性、Symbol键、空对象,这些问题藏得深,调试起来特麻烦。现在我把这些坑点整理出来,你看完就能避开。
不要忽略“可枚举性”:有些属性遍历不到 你有没有遇到过这种情况?明明给对象加了属性,却遍历不到?比如用
定义的属性,默认是不可枚举的,
Object.keys和
for...in都拿不到。我之前做“隐藏设置”功能时,用
Object.defineProperty给对象加了个“secret”属性,结果用
Object.keys遍历不到,导致设置面板一直不显示隐藏内容。
举个例子:
javascript
const obj = {};
// 用Object.defineProperty定义不可枚举属性
Object.defineProperty(obj, ‘secret’, {
value: ‘我是隐藏内容’,
enumerable: false // 默认就是false,不用写也一样
});
// Object.keys拿不到不可枚举属性
console.log(Object.keys(obj)); // 输出:[]
// Reflect.ownKeys可以拿到
console.log(Reflect.ownKeys(obj)); // 输出:[‘secret’]
解决方法很简单:如果需要遍历不可枚举属性,直接用
Reflect.ownKeys;如果不需要,就把
enumerable设为
true(比如
Object.defineProperty(obj, 'secret', { enumerable: true }))。
for...inSymbol键:普通方法拿不到 Symbol是ES6新增的“唯一标识”类型,用来避免属性名冲突。但Symbol键有个特点:普通遍历方法(比如
、
Object.keys)都拿不到它。我之前给用户对象加了个Symbol类型的“uniqueId”,结果用
Object.entries遍历的时候,根本没这个键,导致用户无法登录——查了半小时才发现是Symbol的问题。
Reflect.ownKeys解决方法有两个:
用 :能拿到所有键,包括Symbol;
Object.getOwnPropertySymbols用 :专门拿Symbol键。
举个例子:
javascript
const symKey = Symbol(‘uniqueId’);
const user = {
[symKey]: ‘123456’,
name: ‘赵六’
};
// 用Object.getOwnPropertySymbols拿Symbol键
const symbolKeys = Object.getOwnPropertySymbols(user);
console.log(symbolKeys); // 输出:[Symbol(uniqueId)]
// 遍历Symbol键
symbolKeys.forEach(key => {
console.log(Symbol键:${key.toString()},值:${user[key]});
});
###
null空对象:避免遍历时报错 如果后台返回的对象是
或
undefined,直接遍历会报错(比如
Cannot convert undefined or null to object)。我之前做接口请求时,后台偶尔会返回
null,我没判断就用
Object.entries遍历,结果页面直接崩溃。后来我加了个“对象存在性判断”,再也没出过错。
正确的写法应该是这样的:
javascript
// 假设res.data是后台返回的对象
const data = res.data;
// 先判断对象是否存在,且是对象类型
if (data && typeof data === ‘object’) {
Object.entries(data).forEach(([key, value]) => {
console.log(${key}:${value});
});
} else {
console.log(‘没有数据’);
}
这里要注意:
typeof null会返回
‘object’,所以要先判断
data不是
null(用
data && …),再判断
typeof data === ‘object’,这样才保险。
我把这些方法和坑点整理成了“遍历 cheat sheet”,贴在自己的开发工具里,写代码时直接翻——你也可以把常用的代码复制到自己的代码片段里,省得每次都查文档。其实遍历Object键值对真的不难,关键是要搞清楚“哪些方法能拿到哪些属性”,再避开那些容易踩的坑。你可以把今天的代码复制到项目里试试,要是碰到问题,或者有更顺手的方法,欢迎在评论区告诉我,咱们一起讨论!
你有没有碰到过这种情况?明明给对象加了个属性,用for…in或者Object.keys遍历的时候,死活找不到它?我之前做一个“隐藏功能开关”的设置面板时就踩过这坑——当时想做个默认不显示的开关,用Object.defineProperty给对象加了个“hiddenSwitch”属性,特意把enumerable设成了false(其实默认就是false,不用写也一样)。结果写遍历逻辑的时候,用Object.keys循环,根本没这个属性,设置面板里的开关一直是灰的,用户点不了,我调试了半小时才发现问题出在“不可枚举”上。
其实不可枚举的属性不是真的“藏起来了”,只是for…in和Object.keys这俩方法“看不见”它们——这俩方法只认“可枚举”的属性。那要拿到不可枚举的属性怎么办?有个“全能选手”方法叫Reflect.ownKeys,它能把对象自己的所有属性都捞出来,不管是可枚举的、不可枚举的,还是Symbol类型的键,一个都跑不了。比如我之前那个“hiddenSwitch”的例子,后来换成Reflect.ownKeys遍历,直接就拿到了那个属性,设置面板的开关立刻就亮了。而且它还有个省心的地方:不用像for…in那样还要加hasOwnProperty判断,因为它本来就只遍历对象自己的属性,不会碰原型链上的东西,省了不少多余的代码。
为什么用for…in遍历对象时要加hasOwnProperty判断?
因为for…in会遍历对象自身及其原型链上的所有可枚举属性,如果不加hasOwnProperty判断,很容易拿到原型链上“不该拿的属性”(比如父类的id),导致数据混乱。hasOwnProperty能过滤掉继承来的属性,只保留对象自身的属性。
Object.keys和for…in有什么区别?
Object.keys只返回对象自身的可枚举属性键数组,不会遍历原型链;而for…in会遍历对象自身+原型链上的可枚举属性。 Object.keys返回的是数组,可以用forEach等方法处理,for…in是直接循环键。
Symbol类型的键用什么方法能遍历到?
普通方法(如for…in、Object.keys)无法拿到Symbol键,需要用Reflect.ownKeys(能拿到所有键,包括Symbol)或Object.getOwnPropertySymbols(专门获取Symbol键)。
不可枚举的属性怎么遍历?
不可枚举属性(比如用Object.defineProperty定义且enumerable为false的属性)无法通过for…in或Object.keys遍历,此时可以用Reflect.ownKeys,它能获取对象自身的所有属性(包括不可枚举和Symbol键)。
遍历后台返回的空对象或null会报错,怎么办?
遍历前要先判断对象的存在性和类型:先检查对象不是null/undefined,再用typeof判断是object类型(注意typeof null会返回object,所以要先排除null)。比如“if (data && typeof data === ‘object’)”,这样能避免报错。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!
站长QQ:709466365 站长邮箱:709466365@qq.com