对象的属性遍历
自身属性、继承的属性、可枚举属性、不可枚举属性、symbol属性
对象遍历方法对比表:
| 方法 | 遍历自身属性 | 遍历原型链 | 包含不可枚举 | 包含Symbol | 返回类型 | ES版本 |
|---|---|---|---|---|---|---|
for...in | 部分 | 是 | 否 | 否 | 属性名 | ES5 |
Object.keys() | 是 | 否 | 否 | 否 | 属性名数组 | ES5 |
Object.getOwnPropertyNames() | 是 | 否 | 是 | 否 | 属性名数组 | ES5 |
Reflect.ownKeys() | 是 | 否 | 是 | 是 | 属性名数组 | ES6 |
Object.entries() | 是 | 否 | 否 | 否 | 键值对数组 | ES2017 |
Object.getOwnPropertySymbols() | 是 | 否 | 是 | 仅Symbol | Symbol数组 | ES6 |
对象遍历方法详细对比表:
| 方法 | 遍历范围 | 特点 | 使用场景 | 代码示例 |
|---|---|---|---|---|
for...in | 自身+原型链可枚举属性 | 最早的遍历方法 | 需要遍历继承属性 | for(let key in obj){ } |
Object.keys() | 自身可枚举属性 | 简单直接 | 快速获取属性名 | Object.keys(obj) |
Object.getOwnPropertyNames() | 自身所有属性 | 包含不可枚举 | 获取完整属性 | Object.getOwnPropertyNames(obj) |
Reflect.ownKeys() | 自身所有属性 | 包含Symbol | 最全面的遍历 | Reflect.ownKeys(obj) |
Object.entries() | 自身可枚举属性 | 返回键值对 | 转换对象 | Object.entries(obj) |
Object.getOwnPropertySymbols() | 自身Symbol属性 | 专门获取Symbol | 处理特殊属性 | Object.getOwnPropertySymbols(obj) |
Symbol 属性详解:
- 基本概念
// 创建唯一标识符
let sym1 = Symbol('描述');
let sym2 = Symbol('描述');
console.log(sym1 === sym2); // false
- 作为对象属性
let obj = {
[Symbol('name')]: '张三',
[Symbol('age')]: 20
};
// 特殊访问方式
console.log(obj[Symbol('name')]); // undefined
- 获取 Symbol 属性
// 获取对象的Symbol属性
let symbols = Object.getOwnPropertySymbols(obj);
console.log(symbols); // [Symbol(name), Symbol(age)]
- Symbol 特性
// 不可枚举
for (let key in obj) {
console.log(key); // 空
}
// JSON序列化时被忽略
console.log(JSON.stringify(obj)); // {}
- 常见用途
// 私有属性
const _private = Symbol('private');
class Example {
constructor() {
this[_private] = '私有数据';
}
}
// 唯一标识
const ID = Symbol('id');
- 全局 Symbol
// 全局Symbol
let globalSym = Symbol.for('key');
let otherSym = Symbol.for('key');
console.log(globalSym === otherSym); // true
关键特点:
- 唯一性
- 不可枚举
- 作为特殊属性使用
- 避免属性名冲突