对象字面量属性名会转为字符串或symbol作为键,且默认生成configurable、enumerable、writable均为true的数据描述符;描述符需用object.defineproperty等api显式设置,语法糖不改变默认行为。

对象字面量里写的属性名,和它背后实际的属性描述符之间,并不是“写什么就默认配什么”的简单映射——而是有一套隐式但明确的默认规则。理解这套匹配逻辑,才能避开赋值失效、不可枚举、删不掉、改不了等常见陷阱。
属性名写法决定键的类型,不影响描述符
属性名无论是否加引号(如 name、"full-name"、42 或 [key]),最终都会被转为字符串或 Symbol 作为键。这个转换过程不改变描述符,默认仍按数据属性生成:
- 合法标识符(如
count)可省略引号,键就是字符串"count" - 含短横线、空格或数字开头(如
"user-id"、"123")必须加引号,键仍是字符串 - 计算属性名
{ [k]: v }中,k若为对象或函数,会调用toString()转成字符串(如{ [{}]: 1 }→{ "[object Object]": 1 }) - 数字字面量键(如
{ 100: "hundred" })自动转为字符串"100",与obj["100"]等价
字面量创建的属性默认全是数据描述符
用 { a: 1, b() {} } 这类语法声明的属性,底层都走的是数据属性路径,其描述符默认为:
- configurable: true —— 可删除、可重定义、可改描述符
-
enumerable: true —— 出现在
for...in和Object.keys()中 - writable: true —— 值可被重新赋值
-
value 是你写的值(方法简写
fn() {}本质是把函数赋给value)
注意:没有显式声明 getter/setter,就不会生成存取描述符;哪怕写成 get name() { return this._n; },那也是访问器属性,描述符结构完全不同(含 get/set 字段,不含 value/writable)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
描述符不能靠字面量直接设置,必须用 API 显式干预
你无法在对象字面量里直接写 { a: { value: 1, writable: false } } 来定义描述符——这种写法会被当成普通嵌套对象。要定制描述符,只能事后调用:
Object.defineProperty(obj, "prop", { writable: false, enumerable: false })Object.defineProperties(obj, { prop1: { ... }, prop2: { ... } })- 或用
Object.getOwnPropertyDescriptors()批量读取再修改
常见误操作:想让某个属性不可遍历,却只改了值,没动 enumerable;想锁死属性,却忘了设 configurable: false,结果仍能用 defineProperty 覆盖——描述符是独立控制项,缺一不可。
方法简写和计算属性不改变描述符默认值
ES6 的语法糖只是写法简化,不改变底层行为:
-
greet() { ... }等价于greet: function() { ... },仍是writable: true的数据属性 -
{ [k]: v }创建的属性,和普通字面量属性一样,默认configurable、enumerable、writable全为true - 只有通过
defineProperty显式传入get/set,才会切换成存取描述符,此时value和writable就失效了
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










