在有些开发场景下,可能需要获取一个对象的所有属性字段名,或者同时获取属性字段名和属性值,比如下面的一个普通的对象:
let obj = {
type: 1,
keyword: \'js\'
}
这个 obj 对象只有两个属性字段:type 和 keyword,属性值为 1 和 js,实际过程中的对象可能更加复杂,字段也会更多。
对于遍历一个对象的属性,最容易想到的就是使用 for 循环 这种方式,因为它更直接,而且平时使用也是比较多,除了直接使用 for 循环这种方式外,还有其他的几种方式,这里主要分为三大类,共7中方式:
for循环方式
- for...in
- for...of
Object方法
- Object.keys()
- Object.entries()
- Object.getOwnPropertyNames()
- Object.getOwnPropertySymbols()
Reflect方法
- Reflect.ownKeys()
1、for...in
for...in 语句可以用来循环一个对象所有可枚举的属性,包括继承的属性,下面的代码是用来打印 obj 对象所有的属性字段和属性值:
let obj = {type: 1, keyword: \"js\"};
for (let key in obj) {
console.log(key, obj[key])
}
输出结果如下:
type 1
keyword js
2、for...of
for...of 语句主要用来循环一个可迭代对象的属性,要成为可迭代对象, 一个对象必须实现 @@iterator 方法,这意味着对象(或者它原型链上的某个对象)必须有一个键为 @@iterator 的属性,可通过常量 Symbol.iterator 访问该属性。
对于普通的对象,其实并不是可迭代对象,如果直接使用 for...of 遍历的话,会报错的,下面来测试一下:
let obj = {type: 1, keyword: \"js\"};
for (let key of obj) {
console.log(key, obj[key])
}
运行后,出现下面的错误,直接提示 obj 不是可迭代对象,如下:
那么如何使用 for...of 来遍历对象属性呢,首先需要做的就是将 obj 对象转换成一个可迭代对象,这里可以借助 Object.keys() 方法,调整后的代码如下:
let obj = {type: 1, keyword: \"js\"};
for (let key of Object.keys(obj)) {
console.log(key, obj[key])
}
输出结果如下:
type 1
keyword js
3、Object.keys()
在上面的 for...of 语句中,已经使用了 Object.keys() 方法将 obj 对象转换成了一个可迭代对象,其实也可以直接使用 Object.keys() 方法来遍历一个对象的属性,先来看看它的定义
Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致
测试代码如下:
let obj = {type: 1, keyword: \"js\"};
Object.keys(obj).forEach(key => console.log(key, obj[key]))
输出结果如下:
type 1
keyword js
4、Object.entries()
除了上述的 Object.keys() 方法,还有使用 Object.entries() 方法,它的定义如下:
Object.entries() 方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
测试代码如下:
let obj = {type: 1, keyword: \"js\"};
Object.entries(obj).forEach(item => console.log(item[0], item[1]))
输出结果如下:
type 1
keyword js
这个方法和 Object.keys() 方法的区别在于,它循环返回的结果是键值对,而 Object.keys() 返回的只是对象的属性名称,并不包括值,如果只是想遍历一个对象的所有属性值,那么可以使用另外的一个方法:Object.values()
5、Object.getOwnPropertyNames()
这个方法也可以用来遍历一个对象的属性,它的定义如下:
Object.getOwnPropertyNames() 方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组。
下面来看看测试代码:
let obj = {type: 1, keyword: \"js\"};
Object.getOwnPropertyNames(obj).forEach(key => console.log(key, obj[key]))
输出结果如下:
type 1
keyword js
6、Object.getOwnPropertySymbols()
这个方法也可以用来遍历一个对象的属性,它的定义如下:
Object.getOwnPropertySymbols() 方法返回一个给定对象自身的所有 Symbol 属性的数组。
从它的定义可以看出,它只能用于遍历 Symbol 属性,不能遍历非Symbol 属性,对于一个普通对象,如果没有Symbol 属性,那么其实是无法使用该方法来遍历的,具体测试代码如下:
let obj = {type: 1, keyword: \"js\"};
Object.getOwnPropertySymbols(obj).forEach(key => console.log(key, obj[key]))
无法输出任何结果,因为 obj 对象没有任何 Symbol 属性,使用 Object.getOwnPropertySymbols(obj) 方法,只会得到一个空数组。
下面来定义一个包含 Symbol 属性的对象,同时来遍历一下这个对象的属性:
let type = Symbol(\'type\');
let keyword = Symbol(\'keyword\');
let symbolObj = {};
symbolObj[type] = 1;
symbolObj[keyword] = \'js\';
symbolObj[\'name\'] = \'javascript\';
Object.getOwnPropertySymbols(symbolObj).forEach(key => console.log(key, symbolObj[key]));
输出的结果如下:
Symbol(type) 1
Symbol(keyword) \'js\'
虽然 symbolObj 对象有三个属性,但是只会输出其中的两个 Symbol 属性:Symbol(type) 和 Symbol(keyword) 属性,而不会输出普通属性 name。
7、Reflect.ownKeys()
除了使用 Object 提供的静态方法外,还可以使用 Reflect.ownKeys() 方法来遍历对象属性,首先来看看 Reflect 对象是什么:
Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法,不能通过new 运算符对其进行调用,或者将Reflect对象作为一个函数来调用,Reflect的所有属性和方法都是静态的(就像Math对象)。
再来看看 Reflect.ownKeys() 方法的定义
静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。
从它的定义可以看出,它和 Object.keys() 方法差不多,测试代码如下:
let obj = {type: 1, keyword: \"js\"};
Reflect.ownKeys(obj).forEach(key => console.log(key, obj[key]))
输出结果如下:
type 1
keyword js
参考资料