JavaScript中的属性在内部实现层面是否本身也属于对象?
结论先行
在ECMAScript规范层面,属性本身不是对象;而具体JavaScript引擎的内部实现中,也通常不会将属性直接实现为标准JS对象,只会在必要时转换为对外暴露的对象结构。
规范层面的定义
ECMAScript规范中,和属性对应的元数据结构是属性描述符(Property Descriptor),它属于规范定义的「记录(Record)」类型,仅用来描述属性的行为特征,不属于JS普通对象的范畴:
- 记录是规范层面用来描述结构化数据的抽象类型,和开发者可以操作的普通JS对象是完全不同的概念
- 我们熟知的
[[Configurable]]、[[Enumerable]]、[[Writable]]、[[Value]]、[[Get]]、[[Set]]都是属性描述符这个记录的固定字段,不是对象的属性
引擎实现层面的实际情况
不同JS引擎可以自由选择属性的内部存储方式,只要对外表现符合规范要求即可,目前主流引擎的实现逻辑基本一致:
- 为了优化性能,引擎内部通常会用极为紧凑的二进制结构体来存储属性的元信息,不会额外生成完整的JS对象占用内存
- 只有当开发者主动调用
Object.getOwnPropertyDescriptor()这类API时,引擎才会临时把内部存储的属性元信息,转换为一个普通JS对象返回给开发者,这个返回的对象并不是引擎内部原本存储的结构
补充说明
你在规范中没有找到「属性本身是对象」的明确表述是正常的:ECMAScript规范只定义对外的行为标准,不会约束引擎的内部实现细节,所以不会对这类实现层面的逻辑做强制规定。
内容的提问来源于stack exchange,提问作者coderboy
相关产品推荐
相关产品推荐

