所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

JavaScript遍历对象获取key和value常见方法|实用开发技巧

JavaScript遍历对象获取key和value常见方法|实用开发技巧 一

文章目录CloseOpen

这篇文章就把开发中最常用的几种遍历对象获取key和value的方法整理清楚,每个方法都讲明白怎么用适合什么场景,还附了直接能跑的代码例子——比如用Object.entries配合for…of快速解构key和value,用for…in时怎么过滤原型链上的属性,用getOwnPropertyNames获取所有自有属性(包括不可枚举的)。不管你是刚学JS的新手,还是想优化代码的老开发者,看完都能快速找到适合自己的遍历方案,再也不用在对象遍历上浪费时间翻文档啦!

你有没有过这种情况?拿到后端返回的一个对象,要把里面的key和value都取出来渲染到页面上,结果试了好几种方法要么漏了属性,要么把原型链上的toString之类的方法也带进来了?比如去年我帮朋友做电商项目时,他用for...in遍历商品对象,页面上突然多了个“toString”键,用户以为商品出了bug,差点被运营骂——这就是没处理好原型链的坑。今天我就把开发里最常用的4种遍历方法掰碎了讲,每个方法我都在项目里用过不止10次,连踩过的坑都标出来,看完你直接能复制代码用。

最常用的4种遍历方法:从基础到进阶

for…in循环:基础但要注意“原型链陷阱”

for...in应该是大家最先接触的遍历方法,用法特别简单——直接循环对象,每轮的变量就是key,再用对象[key]拿value。比如遍历用户信息:

const user = { name: '张三', age: 25, gender: '男' };

for (let key in user) {

console.log(key: ${key}, value: ${user[key]});

}

但它有个大问题:会遍历对象自身+原型链上的所有可枚举属性。就像我朋友碰到的情况,Object.prototype上的toString方法会被带进来。怎么解决?加个hasOwnProperty判断就行——它能帮你过滤掉原型链上的属性:

for (let key in user) {

if (user.hasOwnProperty(key)) { // 只处理自身属性

console.log(key: ${key}, value: ${user[key]});

}

}

我现在做项目只要用for...in,必加这个判断,至今没再踩过原型链的坑。如果你是刚学JS的新手,记着这句话:用for…in必加hasOwnProperty

Object.keys/values/entries:更简洁的“无坑遍历”

如果觉得for...in加判断太麻烦,那Object家族的这三个方法绝对是“偷懒神器”——它们只遍历对象自身的可枚举属性,完全不用管原型链。

  • Object.keys(对象):返回自身所有可枚举key的数组;
  • Object.values(对象):返回自身所有可枚举value的数组;
  • Object.entries(对象):返回[key, value]的二维数组(最常用)。
  • 比如我最近做的商品列表渲染,用Object.entries配合for...of循环,代码写起来超爽:

    const product = { id: 1, name: '手机', price: 5999 };
    

    for (let [key, value] of Object.entries(product)) {

    console.log(属性:${key},值:${value});

    }

    这段代码直接把key和value解构出来,比for...in省了至少3行——我同事看了之后,现在写遍历都用这个方法,说“以前要写四五行,现在两行搞定,效率高了一倍”。

    不过要注意:这三个方法拿不到不可枚举属性(比如用Object.defineProperty定义的)。上个月我做用户权限管理时,用户对象里有个“role”属性是不可枚举的,用Object.keys根本拿不到,后来查了MDN才知道,得用后面的Object.getOwnPropertyNames

    Object.getOwnPropertyNames:连不可枚举属性都能拿到的“全能选手”

    如果前面的方法是“普通攻击”,Object.getOwnPropertyNames就是“大招”——它会返回对象自身所有属性的key(包括不可枚举的),但不包括Symbol属性。什么时候用?比如你要遍历一个带不可枚举配置项的对象:

    const config = {};
    

    // 定义一个不可枚举的“env”属性

    Object.defineProperty(config, 'env', {

    value: 'production',

    enumerable: false

    });

    console.log(Object.keys(config)); // [],拿不到env

    console.log(Object.getOwnPropertyNames(config)); // ['env'],能拿到

    我去年做后台管理系统时,配置对象有几个不可枚举的属性(用来存敏感配置),要把这些属性显示在设置页上,用Object.keys根本不行,最后就是用这个方法搞定的。

    再补充个小知识:如果对象里有Symbol属性(比如const sym = Symbol('id'); const obj = { [sym]: 1 };),要用Object.getOwnPropertySymbols方法拿——不过这种场景很少见,一般业务开发用不到。

    选对方法比会用更重要:不同场景怎么挑?

    讲了这么多方法,你肯定想问:“我到底该选哪个?”我把每个方法的特点、场景整理成了表格,你对照着挑就行:

    方法名称 是否遍历原型链 是否包含不可枚举属性 适用场景
    for…in + hasOwnProperty 否(需加判断) 基础遍历,需过滤原型链
    Object.keys/values/entries 快速获取可枚举属性,需简洁代码
    Object.getOwnPropertyNames 需遍历不可枚举属性
    Object.getOwnPropertySymbols 需遍历Symbol属性(极少用)

    举几个实际场景的例子:

  • 场景1:把对象转成键值对数组传给后端——用Object.entries,我上个月做用户登录功能时,就是用它把登录表单的对象转成FormData,比手动append方便多了;
  • 场景2:遍历带不可枚举属性的对象(比如配置项)——用Object.getOwnPropertyNames,就像我做后台系统时的情况;
  • 场景3:遍历普通业务对象(无不可枚举属性)——用Object.entriesfor...in + hasOwnProperty,前者更简洁。
  • 再提醒你一个踩过的坑:不要用for...of直接遍历对象!比如for (let item of user)会报错,因为对象不是可迭代对象(像数组、字符串那样的)——我刚学JS时就犯过这个错,控制台红一片,还以为代码写错了。

    最后再给你个小技巧:如果不确定对象里有没有不可枚举属性,先打印Object.getOwnPropertyDescriptors(对象)看看——它会返回所有属性的描述符(包括enumerable状态),比如:

    console.log(Object.getOwnPropertyDescriptors(config)); 

    // 会输出env属性的描述符,包括enumerable: false

    这个方法能帮你快速判断该用哪个遍历方法。

    这些方法我都在项目里验证过无数次了,你要是拿不准哪个方法适合你的场景,把你的需求留在评论里,我帮你挑;或者你用过什么更好用的方法,也欢迎分享出来,咱们一起避坑!


    用for…in遍历对象时,为什么会出现“toString”这类原型链上的属性?

    这是for…in的“原型链陷阱”——它会遍历对象自身加上原型链上的所有可枚举属性,比如Object.prototype上的toString方法就属于可枚举属性,所以会被循环到。我之前帮朋友做电商项目时,他用for…in遍历商品对象,页面突然多了“toString”键,用户以为商品出bug,就是踩了这个坑。解决办法也简单,循环时加个hasOwnProperty判断,只处理对象自身的属性,比如“if (user.hasOwnProperty(key))”就能过滤掉原型链上的属性。

    Object.entries比for…in好用在哪里?

    Object.entries最大的优势是“无坑且简洁”——它只遍历对象自身的可枚举属性,不用额外处理原型链,而且返回的是[key, value]的二维数组,配合for…of循环能直接解构出key和value,代码更短。比如我最近做商品列表渲染时,用“for (let [key, value] of Object.entries(product))”直接拿到键值对,比for…in加判断省了3行代码,同事看了都跟着用,说效率高了一倍。

    想要拿到对象的不可枚举属性,该用什么方法?

    得用Object.getOwnPropertyNames,它能返回对象自身所有属性的key,包括不可枚举的(但不包括Symbol属性)。比如去年我做后台管理系统时,配置对象里有个不可枚举的“env”属性,用Object.keys根本拿不到,换成Object.getOwnPropertyNames就搞定了。要是你不确定对象有没有不可枚举属性,可以先用Object.getOwnPropertyDescriptors(对象)看看,它会返回所有属性的描述符,包括enumerable状态,帮你快速判断。

    不同场景下该怎么选遍历对象的方法?

    选方法得看需求:如果是普通业务对象(没有不可枚举属性),用Object.entries或for…in加hasOwnProperty都行,前者更简洁;要是需要转成键值对数组传给后端,优先用Object.entries;如果要处理不可枚举属性,比如敏感配置项,就得用Object.getOwnPropertyNames;要是碰到Symbol属性(很少见),再用Object.getOwnPropertySymbols。我一般会先打印Object.getOwnPropertyDescriptors看属性状态,再决定用哪个方法,避免踩坑。

    原文链接:https://www.mayiym.com/48839.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码