推荐答案
遍历对象属性主要有两种常用方法:for...in 循环和 Object.keys() 方法。
for...in 循环:
// www.javascriptcn.com code example
const obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
if (obj.hasOwnProperty(key)) { // 建议使用 hasOwnProperty 过滤原型链上的属性
console.log(key, obj[key]);
}
}
// 输出:
// a 1
// b 2
// c 3Object.keys() 方法:
// www.javascriptcn.com code example
const obj = { a: 1, b: 2, c: 3 };
const keys = Object.keys(obj);
keys.forEach(key => {
console.log(key, obj[key]);
});
// 或者使用 for...of 循环
for (const key of Object.keys(obj)) {
console.log(key, obj[key]);
}
// 输出:
// a 1
// b 2
// c 3区别:
| 特性 | for...in 循环 |
Object.keys() 方法 |
|---|---|---|
| 遍历内容 | 遍历对象自身及其原型链上所有可枚举的属性 | 仅遍历对象自身的可枚举属性 |
| 返回类型 | 无,直接遍历 | 返回一个包含对象自身可枚举属性名的数组 |
| 遍历顺序 | 不保证遍历顺序 (规范中只保证以插入顺序遍历),实践中大多是按照插入顺序,但仍需注意 | 保证按照对象自身属性的插入顺序遍历 |
| 适用场景 | 遍历对象自身和原型链属性(通常需要hasOwnProperty过滤) |
遍历对象自身属性,需要获取属性名数组或进行数组操作时 |
| 健壮性 | 需要hasOwnProperty检查,避免遍历到原型链上的属性。 |
返回数组,更便于处理和使用。 |
本题详细解读
for...in 循环
for...in 循环用于遍历对象的可枚举属性,包括对象自身的属性和从原型链继承来的属性。它的语法如下:
for (let key in object) {
// 执行代码
}其中 key 是属性名,每次循环都会被赋值为对象 object 的一个属性名。由于 for...in 会遍历原型链上的属性,为了只遍历对象自身的属性,通常会在循环体中使用 hasOwnProperty() 方法进行过滤:
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
// 处理自身属性
}
}- 优点:
- 可以遍历对象自身及其原型链上的所有可枚举属性。
- 缺点:
- 会遍历原型链上的属性,需要配合
hasOwnProperty()才能只遍历对象自身的属性。 - 不保证遍历顺序。
- 会遍历原型链上的属性,需要配合
Object.keys() 方法
Object.keys() 方法返回一个由对象自身可枚举属性组成的数组,这些属性名以字符串的形式存在于数组中。
const keys = Object.keys(obj);
得到属性名数组后,可以配合 forEach() 方法或 for...of 循环来遍历属性,例如:
const keys = Object.keys(obj);
keys.forEach(key => {
console.log(key, obj[key]);
});for (const key of Object.keys(obj)) {
console.log(key, obj[key]);
}- 优点:
- 只遍历对象自身可枚举属性,不会遍历原型链上的属性。
- 返回一个数组,方便进行数组操作。
- 保证按照属性插入顺序遍历。
- 缺点:
- 需要额外的数组遍历操作来访问属性值。
遍历属性值
两种方法都可以通过键名来访问属性值,即 obj[key]。
总结
在实际开发中,如果只需要遍历对象自身的属性,并需要一个属性名数组进行操作,则推荐使用 Object.keys() 方法。如果需要遍历对象自身和原型链上的属性,并且需要注意原型链上的属性, 则可以使用 for...in 循环,并结合 hasOwnProperty() 方法进行过滤。