JavaScript对象属性名本质为字符串或Symbol:普通属性名(如obj.name)自动转字符串,计算属性名(如{[expr]:v})支持动态键;遍历时Object.keys只返回字符串键,Reflect.ownKeys包含Symbol键。

JavaScript 中对象的属性名可以是字符串,也可以是通过表达式动态计算得出的,这两种方式在语法和使用场景上有明显区别。
普通属性名:字符串字面量或标识符
最常见的方式是直接写属性名,如 obj.name 或 obj["name"]。此时属性名会被自动转为字符串(即使写的是数字、布尔值等原始值):
-
{ 42: "value" }中的42会被转为字符串"42" -
{ true: "yes", null: "none" }中的true和null同样转为"true"和"null" - 标识符形式(如
name)本质也是字符串,但省略了引号;若含空格、短横线或以数字开头,必须加引号,例如{"first-name": "John"}
计算属性名:用方括号包裹表达式
当属性名需要运行时确定,就得用计算属性名语法:{ [expression]: value }。方括号内可以是任意能返回字符串(或可转为字符串)的表达式:
-
const key = "userAge"; const obj = { [key]: 25 };→{ userAge: 25 } -
{ ["foo" + "bar"]: "result" }→{ foobar: "result" } -
{ [Symbol("id")]: 123 }可用于定义 Symbol 类型键(不会被for...in遍历) - 注意:不能在对象字面量中对同一属性同时使用计算名和简写,例如
{ [k]: v, k }是合法的,但{ [k]: v, [k]: w }会后者覆盖前者
属性访问与遍历中的字符串化行为
无论定义时是否加引号或使用计算名,所有键在底层都以字符串或 Symbol 存储。这影响到遍历和检测:
立即学习“Java免费学习笔记(深入)”;
-
Object.keys(obj)只返回字符串键,忽略 Symbol 键 -
Object.getOwnPropertyNames(obj)返回所有字符串键(包括不可枚举的) -
Reflect.ownKeys(obj)返回全部键(字符串 + Symbol) -
obj[42]和obj["42"]访问的是同一个属性,因为数字42被自动转为字符串"42"
实用建议:何时用哪种写法
选择取决于可读性、维护性和运行时需求:
- 静态、确定的属性名,优先用点号或无引号字面量(
obj.name或{ name: "x" }),更简洁清晰 - 含特殊字符、变量拼接、或依赖运行时逻辑的属性名,必须用计算属性名(
{ [prefix + "Id"]: id }) - 避免把纯数字字面量当“非字符串”使用——它仍是字符串键,且可能被误认为数组索引(尤其在类数组对象中)
- 需要私有或唯一键时,考虑
Symbol配合计算属性名,而非依赖命名约定(如_internal)










