JavaScript对象深度解析:从语法到遍历

168 阅读2分钟

1. 对象基础

1.1 语法形式

文字形式

const obj = { 
  name: 'Alice',
  age: 28 
};

构造形式

const obj = new Object();
obj.name = 'Alice';
obj.age = 28;

在文字声明中,你可以添加多个键/值对,但是在构造形式中,你必须逐个添加属性。

1.2 类型体系

类型示例特性
普通对象{}键值对集合
包装对象new Number(42)原始值包装
内置对象Array, Date语言内置类型
函数对象function Foo(){}可调用对象

2. 对象内容

2.1 属性管理

可计算属性名

const dynamicKey = 'user_' + Date.now();
const obj = {
  [dynamicKey]: '动态属性'
};

属性 vs 方法

const calculator = {
  // 属性
  PI: 3.1415926,
  
  // 方法
  sum: function(a, b) {
    return a + b;
  }
};

2.2 特殊对象

数组特性

const arr = [1, 2, 3];
console.log(arr.length); // 3
arr['customProp'] = 'value'; // 非标准用法

2.3 对象操作

深度复制

// 浅拷贝
const copy1 = Object.assign({}, original);

// 深拷贝
const copy2 = JSON.parse(JSON.stringify(original));

2.4 属性控制

属性描述符

Object.defineProperty(obj, 'secret', {
  value: 'confidential',
  writable: false,
  enumerable: false
});

对象不变性

方法效果示例
Object.preventExtensions禁止新增属性Object.preventExtensions(obj)
Object.seal密封对象(禁止增删属性)Object.seal(obj)
Object.freeze完全冻结对象Object.freeze(obj)

2.5 访问机制

[[Get]] 流程

graph TD
    A[属性访问] --> B{对象自身属性}
    B -->|存在| C[返回值]
    B -->|不存在| D[原型链查找]
    D --> E{找到属性?}
    E -->|是| F[返回值]
    E -->|否| G[返回undefined]

[[Put]] 过程

  1. 检查属性是否存在访问器描述符(setter)
  2. 验证属性是否可写(writable)
  3. 执行赋值操作或触发TypeError

2.6 访问器属性

const bankAccount = {
  _balance: 1000,
  
  get balance() {
    return this._balance + ' USD';
  },
  
  set balance(value) {
    if(value < 0) throw new Error('余额不能为负');
    this._balance = value;
  }
};

3. 存在性与遍历

3.1 存在性检查

// 检查自有属性
obj.hasOwnProperty('key');

// 包含原型链检查
'toString' in obj; // true

3.2 遍历方法对比

方法返回值包含原型链示例
for...in可枚举属性名for(let key in obj)
Object.keys()自有可枚举属性名数组Object.keys(obj)
Object.getOwnPropertyNames()所有自有属性名Object.getOwnPropertyNames(obj)
Reflect.ownKeys()包括Symbol属性Reflect.ownKeys(obj)

4. 最佳实践

  1. 优先使用对象字面量:比构造形式更简洁高效
  2. 合理使用属性描述符:精确控制对象行为
  3. 注意深浅拷贝区别:根据场景选择复制方式
  4. 慎用for...in遍历:原型链属性可能带来意外结果
  5. 利用现代语法
// 属性值简写
const name = 'Bob';
const obj = { name };

// 方法简写
const obj = {
  sayHi() {
    console.log('Hello!');
  }
};

5. 进阶方向

  • 原型继承机制
  • ES6 Proxy对象
  • 对象性能优化
  • WeakMap/WeakSet特殊存储

通过深入理解对象系统,开发者可以更好地驾驭JavaScript的核心特性,构建更健壮的应用程序。