游乐游手机版
首页/前端开发/文章详情

Reflect.ownKeys结合数组过滤实现对象私密属性精准销毁

时间:2026-07-06 06:55
通过反射机制获取对象所有自身属性键(包括不可枚举和符号键),利用数组定义的黑名单或白名单,逐个遍历这些键并执行删除操作或将其赋值为未定义,从而实现敏感属性的精准销毁,并支持对不可配置属性进行降级处理。

先澄清一点:Reflect.ownKeys 本身并不负责“销毁”属性,它的职责是枚举对象自身的所有键——包括不可枚举和 Symbol 键。要真正删除属性,仍需借助 delete 运算符或将属性值赋为 undefined。而数组过滤在此充当“声明者”角色:通过白名单或黑名单定义敏感字段,再结合 Reflect.ownKeys 获取全部自有键,进行交集或排除,最终精准定位并清理目标属性。

下面一步步拆解这个流程。

明确敏感字段列表,通过数组定义白名单或黑名单

第一步,先把需要销毁的敏感属性名整理出来。例如常见的 "password""token""idCard",甚至可能包含 Symbol("session")。将这些名称存储为字符串或 Symbol 类型的数组。特别注意:Symbol 键必须使用原始的 Symbol 实例,不能通过 Symbol("xxx") 临时生成——因为每次调用都会创建新的 Symbol,无法匹配。

  • 黑名单模式(销毁指定字段):blacklist = ["password", "token", Symbol.for("auth")];
  • 白名单模式(仅保留指定字段):whitelist = ["id", "name", "email"]; // 其余全部删除

用 Reflect.ownKeys 获取全部自有键,包含不可枚举与 Symbol 键

Reflect.ownKeys(obj) 返回一个数组,包含了对象所有自有属性的键。其顺序为:先按整数索引升序(对类数组对象也适用),然后按字符串键的创建顺序,最后是 Symbol 键。相较于 Object.keys()Object.getOwnPropertyNames()Reflect.ownKeys 更加全面——能够捕获通过 Object.defineProperty 设置的不可枚举属性,以及 Symbol 属性。

举个例子:

const user = { name: "Alice" };
Object.defineProperty(user, "password", { value: "123", enumerable: false });
user[Symbol("token")] = "abc";
Reflect.ownKeys(user); // ["name", "password", Symbol(token)]

你看,password 虽不可枚举,Symbol("token") 虽是 Symbol,却无一遗漏。

遍历所有键并执行精准删除

获取全部键后,逐个判断是否属于敏感列表。若是,则通过 delete obj[key] 移除。这里有一个需要注意的地方:如果属性是不可配置的(configurable: false),delete 会静默失败(严格模式下会抛错)。此时,可以将属性值赋为 undefinednull,作为逻辑上的“销毁”。

  • 黑名单方式(推荐):遍历 Reflect.ownKeys 返回的键,判断每个 key 是否存在于 blacklist 中,若是则执行 delete。
  • 白名单方式:先提取 whitelist 中实际存在的键,再遍历所有 ownKeys,不在 whitelist 中的都 delete。
  • Symbol 匹配需确保引用一致:使用 Symbol.for("key") 注册全局 Symbol,或直接复用定义时的 Symbol 常量。

封装成可复用的安全清理函数

最后,将上述逻辑封装成一个函数,支持传入目标对象和敏感字段数组,还可扩展配置项(如是否启用严格模式),以提高复用性和健壮性。

function scrubSensitive(obj, sensitiveKeys) {
  if (typeof obj !== 'object' || obj === null) return obj;
  const keys = Reflect.ownKeys(obj);
  for (const key of keys) {
    if (sensitiveKeys.some(s => 
      (typeof s === 'symbol' && s === key) || 
      (typeof s === 'string' && s === key)
    )) {
      try {
        delete obj[key];
      } catch (e) {
        obj[key] = undefined; // fallback for non-configurable props
      }
    }
  }
  return obj;
}

// 使用示例
const data = { name: "Bob", password: "x", [Symbol("api")]: "secret" };
scrubSensitive(data, ["password", Symbol.for("api")]);

如此一来,无论对象中包含多少不可枚举、Symbol 或不可配置的属性,都能精准按需清理,且不影响其他正常字段。再次强调:Reflect.ownKeys 只负责枚举属性,真正的“销毁”仍需通过 delete 或赋值为 undefined 实现,两者配合才能打出漂亮的组合拳。

来源:https://www.php.cn/faq/2756082.html
上一篇正则表达式实现高性能文本索引的方法与技巧 下一篇HTML datalist标签与input配合实现原生下拉联想与代码质量解析
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Layui弹出层监听子页面键盘快捷键实现方法
前端开发 · 2026-07-06

Layui弹出层监听子页面键盘快捷键实现方法

子页面键盘事件监听需在DOM加载完成后绑定,父页无法直接监听子页按键,必须由子页自身监听后通过parent或postMessage通知父页。典型写法为子页调用父页已定义的关闭函数。需注意焦点状态、输入法及layui版本兼容性等陷阱。

Layui表单提交时携带当前页面Meta信息的实现方法
前端开发 · 2026-07-06

Layui表单提交时携带当前页面Meta信息的实现方法

Layui表单提交不会自动携带页面Meta信息,需在form on( submit )回调中手动读取meta内容并拼接到表单数据,注意后端字段映射及特殊字符编码,多meta时按需选取。

HTML5拖拽事件流状态转移监控调试
前端开发 · 2026-07-06

HTML5拖拽事件流状态转移监控调试

HTML5拖拽事件流易因漏监听或未调用preventDefault而中断。需掌握dragstart设置数据、dragover接受放置、drop触发条件等关键点。通过统一日志捕获事件上下文、识别常见状态丢失场景并配合可视化面板,可清晰定位拖拽过程断点。

uni-app实现小红书商品详情图卡片切换
前端开发 · 2026-07-06

uni-app实现小红书商品详情图卡片切换

通过手写touch事件与transform控制五张卡片,动态计算translateX、scale、opacity及z-index模拟层叠滑动效果。滑动距离超过80rpx触发切换,否则复位。图片仅渲染当前及前后两张,有效优化加载性能与渲染效率。

图像旋转倾斜与扭曲的Canvas像素矩阵变换
前端开发 · 2026-07-06

图像旋转倾斜与扭曲的Canvas像素矩阵变换

Canvas图像变形本质是操作坐标系,图像被动跟随。旋转需先平移原点至目标中心再旋转后复位;倾斜通过仿射变换矩阵实现;扭曲无原生API,可用分块模拟或转用WebGL。每次变换前保存状态,完成后恢复,避免坐标系偏移。