Object.seal()仅作用于目标对象自身,不影响其原型链或以它为原型的实例;要限制实例属性增删,须直接对实例调用Object.seal()。

不能用 Object.seal() 直接“密封原型对象”来限制实例属性的增删——这是个常见误解。因为 Object.seal() 只作用于**目标对象自身**,不影响其原型链上的对象,更不会阻止实例在自身上添加新属性。
为什么 seal 原型对实例无效?
Object.seal() 仅冻结传入的那个对象:设置其 [[Extensible]] = false,并将已有自有属性设为不可配置(但可写)。它不改变原型链行为,也不影响以该对象为原型的其他对象。
例如:
const proto = { x: 1 };
Object.seal(proto);
const obj = Object.create(proto);
obj.y = 2; // ✅ 成功!obj 自身仍可扩展(proto 被 seal 不影响 obj)
obj.x = 99; // ✅ 成功!x 是继承属性,赋值会在 obj 自身创建新属性 y,不修改 proto
想限制实例属性增删?得 seal 实例本身
若希望某个具体对象(如实例)不能新增/删除属性,应直接对其调用 Object.seal():
立即学习“Java免费学习笔记(深入)”;
- 实例化后立即 seal:
const inst = new MyClass(); Object.seal(inst); - 构造函数内 seal:
function MyClass() { Object.seal(this); } - 注意:这仅保护该实例,不影响其他实例或原型
想统一控制所有实例的可扩展性?需配合 constructor 或 class 设计
JavaScript 没有内置机制让“所有以某原型为原型的对象自动不可扩展”。但可通过以下方式模拟约束:
- 在构造函数中强制 seal 实例:
class SealedClass { constructor() { Object.seal(this); } } - 使用
Object.setPrototypeOf(obj, sealedProto)后再 sealobj—— 但原型被 seal 本身无实际防护作用 - 真正需要“禁止继承时扩展”,应结合
Object.preventExtensions()+ 显式设计(如只暴露不可变接口)
密封原型的唯一真实用途
密封原型对象本身,仅用于防止有人意外修改原型结构(如删掉方法、重定义属性描述符):
-
Object.seal(Array.prototype)防止全局污染(不推荐,会破坏环境) - 模块内私有原型:确保你定义的方法不会被外部 delete 或重新 define
- 注意:即使原型被 seal,子对象仍可自由扩展,继承关系不受限
不复杂但容易忽略:seal 的作用域永远是“传进去的那个对象”,不是它的后代,也不是它的使用者。想管住实例,就 seal 实例;想管住原型定义,就 seal 那个原型对象——两者目的不同,不能互相替代。


















