JavaScript遍历对象属性

JavaScript遍历对象属性

最近在做一个项目时,遇到一个遍历对象属性的需求(后来我才知道专业的叫法应该是遍历对象的键值),我使用了熟悉的 Object.kes() 方法去将对象的属性生成一个数组,然后接着对每个属性进行一些操作。

代码如下:

data.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"cat": {
"name": "猫",
"url": "./assets/images/cat.jpg",
"title": "一只正在看着电脑屏幕的夜猫子"
},
"dog": {
"name": "小狗",
"url": "./assets/images/dog.jpg",
"title": "一只可爱的小狗"
},
"planet": {
"name": "星球",
"url": "./assets/images/planet.jpg",
"title": "令人震撼的星球"
},
"grass": {
"name": "草丛",
"url": "./assets/images/grass.jpg",
"title": "一片生意盎然的草地"
},
"magic": {
"name": "魔幻",
"url": "./assets/images/magic.jpg",
"title": "具有魔幻色彩的世界"
}
}

index.js
1
2
3
4
5
import images from './data.json'

Object.keys(images).forEach((item) => {
console.log(item.name)
})

结果

为什么会出现这种情况呢?因为 Object.keys() 方法返回的是参数对象自身的(不含继承的)所有可遍历属性的键名组成的数组。

对象的键名和键值

这里出现了一个很重要的概念——键名。我们知道一个对象是有一个或多个键值对组成,每个键值对都包含一个键名和一个键值。

1
2
3
4
5
cat: {
name: '猫',
url: './assets/images/cat.jpg',
title: '一只正在看着电脑屏幕的夜猫'
},

如,上面这个对象就包含了3个键值对,第一个键值对是 name: '猫',键名是 'name' ,键值是 '猫'。键名一定是字符串类型,而键值则不一定是字符串类型。因为键值也可能是一个对象,比如这个

1
2
3
4
5
6
7
const images = {
cat: {
name: '猫',
url: './assets/images/cat.jpg',
title: '一只正在看着电脑屏幕的夜猫子'
}
}

images 对象包含了1个键值对,键值对的键名是 'cat',键值是下面这个对象

1
2
3
4
5
{
name: '猫',
url: './assets/images/cat.jpg',
title: '一只正在看着电脑屏幕的夜猫子'
}

一句话总结,对象由一个或多个键值对组成,键名一定是字符串类型,而键值则不一定。

Object.keys() 方法

我们回到上面那个问题,再看一眼 index.js 的代码,结合上面说的 Object.keys() 返回的是一个由对象自身所有可遍历(不含继承的)的键名数组,我们又知道键名仅仅只是一个字符串,每次迭代中的 item 都仅仅是一个字符串,那item.name 自然也就是 undefined 的了。

所以,我们可以将代码改成这样

index.js
1
2
3
4
5
import images from './data.json'

Object.keys(images).forEach((item) => {
console.log(images[item].name)
})

结果

拿到键名后,我们可以借助于原对象取得每个 item 的 name 值。

Object.values() 方法

可能是和我有着相同需求的程序员越来越多吧,ES7 引入了 Object.values() 方法,它返回一个由对象自身的(不含继承的)所有可遍历属性的键值。这个方法就能完美地完成我们的需求啦!修改后的代码如下:

index.js
1
2
3
4
5
import images from './data.json'

Object.values(images).forEach((item) => {
console.log(item.name)
})

结果

总结

  1. Object.keys() 返回一个由对象自身的(不含继承的)所有可遍历属性的键名组成的数组
  2. Object.values() 返回一个由对象自身的(不含继承的)所有可遍历属性的键值组成的数组

此外,遍历对象的方法还有 for...in 以及 Object.entries() (返回一个由对象自身的(不含继承的)所有可遍历属性的键值对组成的数组),这里不再赘述。

最后,还有一点需要注意的是,如果我们的关注点仅仅是键值的话,而完全不需要使用键名的话,我们大可不必使用这个结构,将其改成数组形式更好,如

1
2
3
4
5
6
7
8
const images = [
{
name: '猫',
url: './assets/images/cat.jpg',
title: '一只正在看着电脑屏幕的夜猫子'
},
...
]