对象字面量用于简洁创建对象结构,属性描述符则精细化控制属性行为;二者分层协作:字面量定义“写什么”,描述符决定“怎么写、谁来写、能不能写”。

对象字面量本身是创建对象的简洁语法,而属性描述符(通过 Object.defineProperty 或 Object.defineProperties)控制属性的可读、可写、可枚举、可配置等行为。两者常配合使用:先用字面量快速构建结构,再用描述符精细化控制关键属性的行为。
保护核心配置项不被意外修改
应用初始化时常用字面量定义配置对象,但某些字段(如 API 地址、超时时间)应禁止运行时篡改或删除。
- 先用字面量声明基础配置:
const config = { apiBase: "https://api.example.com", timeout: 5000 }; - 再用
Object.defineProperty锁定关键属性:Object.defineProperty(config, "apiBase", { writable: false, configurable: false }); - 此时
config.apiBase = "xxx"不生效(严格模式下报错),delete config.apiBase也失败
实现只读计算属性
字面量无法直接定义 getter,但可通过描述符在已有对象上添加“伪属性”——访问时动态计算,且不可赋值。
- 创建基础对象:
const user = { firstName: "Alice", lastName: "Smith" }; - 添加只读的全名属性:
Object.defineProperty(user, "fullName", { get() { return `${this.firstName} ${this.lastName}`; }, enumerable: true }); -
user.fullName返回拼接结果,user.fullName = "xxx"无效(无 setter 且未设writable)
隐藏内部状态,仅暴露可控接口
字面量适合表达公开结构,而私有字段(如缓存、计数器)可通过不可枚举的描述符属性隔离。
- 定义公开对象:
const cache = { set(key, value) { this._data[key] = value; }, get(key) { return this._data[key]; } }; - 添加不可枚举的内部存储:
Object.defineProperty(cache, "_data", { value: {}, writable: true, enumerable: false, configurable: false }); -
for...in和Object.keys(cache)不会包含_data,避免误操作或序列化泄露
批量设置多个受控属性
当需要统一约束一组属性(如所有事件处理器必须可配置但不可枚举),Object.defineProperties 比多次调用 defineProperty 更清晰。
- 先建空对象:
const emitter = {}; - 批量定义事件方法:
Object.defineProperties(emitter, { on: { value: function(fn) { /*...*/ }, writable: true, enumerable: false, configurable: true }, emit: { value: function(event) { /*...*/ }, writable: true, enumerable: false, configurable: true } }); - 所有方法默认不可枚举,但保留可重定义能力(
configurable: true),便于测试时替换
这种组合不是替代关系,而是分层协作:字面量负责“写什么”,描述符负责“怎么写、谁来写、能不能写”。实际开发中,多数对象用字面量足矣;只有当需要精确控制属性行为时,才引入描述符补足能力。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











