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);
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]] 过程
- 检查属性是否存在访问器描述符(setter)
- 验证属性是否可写(writable)
- 执行赋值操作或触发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;
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. 最佳实践
- 优先使用对象字面量:比构造形式更简洁高效
- 合理使用属性描述符:精确控制对象行为
- 注意深浅拷贝区别:根据场景选择复制方式
- 慎用for...in遍历:原型链属性可能带来意外结果
- 利用现代语法:
const name = 'Bob';
const obj = { name };
const obj = {
sayHi() {
console.log('Hello!');
}
};
5. 进阶方向
- 原型继承机制
- ES6 Proxy对象
- 对象性能优化
- WeakMap/WeakSet特殊存储
通过深入理解对象系统,开发者可以更好地驾驭JavaScript的核心特性,构建更健壮的应用程序。