javascript中无直接检测属性可写性的方法,需用reflect.getownpropertydescriptor()获取描述符并依类型判断:数据属性看writable,访问器属性看set是否存在且为函数。

JavaScript 中 Reflect 本身没有直接提供“检测属性是否可写”的方法,但可以通过 Reflect.getOwnPropertyDescriptor() 获取属性描述符,再检查其 writable 字段来判断。
用 Reflect.getOwnPropertyDescriptor 拿到属性描述符
这是最标准的方式。该方法返回一个描述符对象(含 value、writable、configurable、enumerable 等字段),其中 writable 布尔值就表示该属性是否可写。
- 如果属性存在且是数据属性,
writable字段明确指示是否允许赋值修改 - 如果属性是访问器属性(有
get/set),则writable为undefined,此时需看是否存在set函数来判断是否“可设置” - 如果返回
undefined,说明属性不存在(或被继承但不可枚举且未显式定义)
区分数据属性和访问器属性
仅看 writable 不够全面。实际判断“能否写入”要分情况:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 数据属性:关注
descriptor.writable === true - 访问器属性:
writable不存在,应检查descriptor.set是否为函数 - 注意:即使
set存在,若其内部抛错或空实现,逻辑上仍可能“不可写”,但 JS 层面认为它是可设置的
封装一个安全的 isWritable 工具函数
可以这样写一个通用判断函数:
function isWritable(obj, key) {
const desc = Reflect.getOwnPropertyDescriptor(obj, key);
if (!desc) return false; // 属性不存在
if ('value' in desc) return desc.writable === true;
if ('set' in desc) return typeof desc.set === 'function';
return false;
}
使用示例:
const obj = { a: 1 };
Object.defineProperty(obj, 'b', { value: 2, writable: false });
Object.defineProperty(obj, 'c', { set(v) { this._c = v; } });
console.log(isWritable(obj, 'a')); // true
console.log(isWritable(obj, 'b')); // false
console.log(isWritable(obj, 'c')); // true
console.log(isWritable(obj, 'd')); // false
注意原型链和不可扩展对象
getOwnPropertyDescriptor 只查自身属性,不沿原型链查找。如果想检查原型上的属性是否可写,需手动遍历原型链。
- 对
Object.preventExtensions()或Object.seal()后的对象,新增属性会失败,但已有属性的可写性不变 -
Object.freeze()会把所有自有属性设为writable: false,此时isWritable返回false
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










