object.seal仅密封对象自身结构,不冻结嵌套属性值;需递归seal所有子对象并配合const声明、安全导出(如getter或冻结副本)才能真正防护html编辑器配置。

Object.seal 不能冻结 HTML 编辑器配置的值,只能锁结构
直接调用 Object.seal(editorConfig) 后,你仍能执行 editorConfig.toolbar = ['bold', 'italic'] 或 editorConfig.maxLength = 5000——只要这些属性原本是 writable: true。它只禁止增删键、禁止 delete editorConfig.mode、禁止 Object.defineProperty(editorConfig, 'mode', { writable: false }),但不碰值本身。
HTML 编辑器配置(如 quill、tiptap、自研富文本)通常含嵌套对象(formats、clipboard、keyboard)、数组(toolbar)、函数(onUpdate),这些全都不受 seal 约束。
- 常见破功现象:
editorConfig.clipboard.matchers.push(...)依然成功;editorConfig.formats.image = { sanitize: false }直接生效 - 真正要防的是“结构漂移”:比如业务方误写
editorConfig.toolBar(驼峰错拼)或删掉formats导致渲染异常 -
seal的价值在于让这类错误在运行时立刻暴露(严格模式下报TypeError),而非静默失败后引发难以定位的 UI 异常
必须递归 seal 所有嵌套子对象,否则等于没封
编辑器配置极少扁平。典型结构如:
const editorConfig = {
toolbar: ['bold', 'link'],
formats: { image: { size: 'responsive' } },
clipboard: { matchVisual: true },
keyboard: { bindings: {} }
};
仅 Object.seal(editorConfig) 后,editorConfig.formats.image.size = 'fixed' 依然合法——因为 formats 和 image 都是未密封的普通对象。
- 必须手动 seal 每一层可变子对象:
Object.seal(editorConfig.formats)、Object.seal(editorConfig.formats.image)、Object.seal(editorConfig.clipboard) - 数组不能靠
seal防篡改:editorConfig.toolbar.push('blockquote')仍会成功;若需禁用修改,得用Object.freeze(editorConfig.toolbar) - 函数属性(如
onCreate)无法被seal锁定行为,但可设为configurable: false防替换——这步seal已自动完成
导出时绝不能返回原始引用,必须用 getter 或副本
哪怕配置已完整 seal,只要模块导出 export const EDITOR_CONFIG = editorConfig,外部就能拿到原始引用并继续操作嵌套层。这是最常被忽略的漏洞点。
- ❌ 错误导出:
export { editorConfig };→ 外部import { editorConfig } from './config'; editorConfig.formats.image = {};仍可执行(因formats未 seal) - ✅ 安全导出 1(只读访问器):
export const getEditorConfig = (key) => editorConfig[key];—— 至少防止遍历误改,且可加字段白名单校验 - ✅ 安全导出 2(冻结副本):
export const EDITOR_CONFIG = Object.freeze({ ...editorConfig });—— 注意这仍是浅冻结,需先对editorConfig及其所有子对象完成 seal/freeze - 关键字段建议用
Symbol键(如editorConfig[Symbol.for('internal:version')]),避免被for...in或解构意外读取
seal 不防变量重赋值,const + ESM 导出才是第一道防线
Object.seal 对 editorConfig = {...} 这类赋值完全无效。它只管对象内部,不管变量绑定。防覆盖靠的是语言机制,不是对象方法。
- 必须用
const editorConfig = {...}; Object.seal(editorConfig);——const阻止重赋值,seal阻止内部结构变化,二者缺一不可 - ESM 模块默认导出绑定不可重写:
export default editorConfig;后,外部import config from './config'; config = {};在运行时直接报错 - 若配置需动态初始化(如从 localStorage 加载),务必在初始化完成后、任何
import发生前立即 seal,否则其他模块可能已持有未密封的引用 - 上线前加一道检查:
console.assert(Object.isSealed(editorConfig), 'EDITOR_CONFIG not sealed!');,配合 CI 脚本拦截
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











