精确动态审计javascript对象状态需按object.isextensible→issealed→isfrozen顺序递进检测,三者呈层级约束关系:前者为后者前提,各自检验对象扩展性、属性可配置性、数据属性可写性,且均不递归检查嵌套对象。

要精确动态审计 JavaScript 对象的状态,关键不是“一次性判断”,而是理解 Object.isExtensible、Object.isSealed、Object.isFrozen 三者之间的层级关系和各自检测的边界条件。它们不是互斥选项,而是递进约束——就像安检的三道关卡,后一道默认包含前一道的要求。
isExtensible:第一道门槛——能否加新属性
这是最基础的检测。它只关心对象是否被禁止新增自身属性,不涉及已有属性的可配置性或可写性。
- 返回
true:对象仍允许通过obj.newKey = value或Object.defineProperty添加新属性 - 返回
false:对象已调用Object.preventExtensions(),或本身是不可扩展的内置对象(如数组字面量冻结后) - 注意:对原始值(
1、"str"、null、undefined)调用会直接返回false(ES6+ 规范)
isSealed:第二道门槛——能否删或重定义已有属性
它在 isExtensible === false 的基础上,进一步要求所有自身属性的 configurable 为 false。这意味着你不能删除属性,也不能用 Object.defineProperty 改变其描述符(比如把 writable: true 改成 false)。
- 返回
true:对象不可扩展 + 所有自有属性configurable: false - 即使某个属性
writable: true,只要满足上述两点,isSealed仍为true - 典型操作:
Object.seal(obj)会同时触发这两项限制
isFrozen:最终门槛——能否修改任何自有数据属性的值
这是最严格的检测。它要求对象同时满足:
– 不可扩展
– 所有自身属性不可配置
– 所有自身数据属性(非 accessor)不可写
-
Object.freeze(obj)是达成该状态的标准方式 - 访问器属性(
get/set)只要configurable: false,就符合要求;isFrozen不检查其writable(因为访问器没有writable) - 重要提醒:它只检测对象自身属性,不递归检查嵌套对象。例如
Object.freeze({a: {b: 1}})中a仍是可变对象,isFrozen却返回true
组合使用实现动态审计逻辑
单次调用任一方法只能反映当前快照。若需“动态审计”,应建立状态流转意识,并配合手动校验:
- 按顺序调用:先
isExtensible,再isSealed,最后isFrozen。若某一步为false,后续无需执行(例如isExtensible === true时,isFrozen必为false) - 发现
isFrozen === false但预期应冻结?检查三项是否全部满足:运行Object.isExtensible(obj)、遍历Object.getOwnPropertyNames(obj)检查每个属性的configurable和writable - 对嵌套结构做深度审计?需递归遍历所有自有属性,对每个对象值单独调用
isFrozen;也可封装一个deepIsFrozen工具函数











