object.isextensible(obj) 返回 false 即表明对象不可扩展,这是最标准轻量的检测方式;它反映对象当前可变性状态而非类型归属,需配合 issealed 和 isfrozen 进一步区分防护级别。

检测不可扩展的对象类型,核心是用 Object.isExtensible() 判断对象是否还能添加新属性,而不是靠构造函数或 instanceof 去识别“是什么类”。它关注的是对象当前的**可变性状态**,而非类型归属。
直接判断对象是否不可扩展
Object.isExtensible(obj) 返回 false 就说明该对象已被标记为不可扩展。这是最标准、最轻量的检测方式:
- 对普通对象,调用
Object.preventExtensions(obj)后,isExtensible立即返回false - 密封(
Object.seal)和冻结(Object.freeze)的对象也必然不可扩展,所以同样返回false - 原型链上的状态不影响自身:父对象不可扩展,子对象仍可能可扩展
- 注意:ES6 起,传入非对象(如字符串、
null、undefined)会返回false;ES5 则抛错,实际使用建议先做类型守卫
区分不可扩展、密封与冻结
仅靠 isExtensible === false 不能确定对象处于哪种防护级别,需组合其他 API:
- 再调
Object.isSealed(obj):若为true,说明属性不可配置(不能删、不能改描述符) - 再调
Object.isFrozen(obj):若为true,说明还额外禁止修改数据属性值(writable: false) - 三者关系是包含关系:冻结 ⇒ 密封 ⇒ 不可扩展,但反过来不成立
避开常见误判陷阱
很多开发者试图用其他方式“间接推断”不可扩展性,容易出错:
-
typeof obj === 'object'或obj.constructor === Object无法反映扩展性,只说明基础类型 -
obj instanceof Object对所有对象都为true,且对null报错,不适用 -
Object.getPrototypeOf(obj) === Object.prototype只说明原型链起点,与是否可扩展无关 - Proxy 对象默认透传目标原型,
isExtensible检测的是 Proxy 实例本身——如果被preventExtensions处理过,就返回false;否则返回true,哪怕 target 已不可扩展
实际检测建议流程
安全、通用的对象扩展性检测可按这个顺序来:
- 先确认是否为对象:
obj !== null && typeof obj === 'object' - 再调
Object.isExtensible(obj)获取结果 - 如需进一步分类,依次叠加
isSealed和isFrozen - 若涉及 Proxy,且需检查其 target 的状态,应先用
obj instanceof Proxy判断,再谨慎访问内部 target(需确保 trap 已定义getPrototypeOf)











