检测 javascript 原型是否被密封最直接的方法是使用 object.issealed(),它会返回一个布尔值表示对象是否被密封;2. 密封对象后不能添加或删除属性,但可以修改现有属性值,而冻结对象(object.freeze())则完全禁止修改;3. 密封操作不影响原型链上的属性查找,实例仍可正常继承和访问原型方法,且可在实例上覆盖方法而不影响被密封的原型。

检测 JavaScript 原型是否被密封,最直接的方法就是使用
Object.isSealed()

Object.isSealed()
Object.freeze()
举个例子,假设我们有一个构造函数
MyClass
prototype

function MyClass() {
this.value = 1;
}
// 正常情况下,原型是可以被修改的
console.log(Object.isSealed(MyClass.prototype)); // false
// 我们可以给原型添加一个方法
MyClass.prototype.getValue = function() {
return this.value;
};
// 现在我们来密封它
Object.seal(MyClass.prototype);
console.log(Object.isSealed(MyClass.prototype)); // true
// 尝试添加新属性(会失败,严格模式下报错)
try {
MyClass.prototype.newValue = 2;
} catch (e) {
console.log("尝试添加新属性失败:", e.message); // TypeError: Cannot add property newValue, object is not extensible
}
// 尝试删除已有属性(会失败,严格模式下报错)
try {
delete MyClass.prototype.getValue;
} catch (e) {
console.log("尝试删除已有属性失败:", e.message); // TypeError: Cannot delete property 'getValue' of #<Object>
}
// 但是,修改现有属性的值是允许的
MyClass.prototype.getValue = function() {
return this.value + 10;
};
console.log(new MyClass().getValue()); // 11我个人觉得,理解这些“锁”的级别非常重要,它决定了你的对象能有多大的灵活性或者说有多大的“安全感”。
这个问题其实挺核心的,也是很多人容易混淆的地方。说白了,密封(
Object.seal()
Object.freeze()

Object.seal()
Object.seal()
Object.freeze()
Object.freeze()
Object.seal()
Object.freeze()
还有个
Object.preventExtensions()
preventExtensions
seal
freeze
在日常的JavaScript开发中,我们可能不会频繁地去检测一个原型是不是被密封了,但总有一些场景,这种检测能力会变得非常有用,甚至可以说是必要的。
一个很重要的原因是防御性编程。想象一下,你正在开发一个库或者框架,你对外暴露了一些构造函数,它们的
prototype
isSealed
再比如,在调试复杂系统时,如果一个对象表现出奇怪的行为,比如某个属性突然不见了,或者无法添加新属性,那么检查它的原型是否被密封,可以帮助你快速定位问题。这就像是你在排查一个机器故障,发现某个零件无法拆卸或更换,你就会去检查是不是有什么特殊的锁具限制了它。
另外,代码审计或安全性检查时,也可能需要关注这一点。特别是当你的代码运行在共享环境中,或者需要确保某些核心对象的完整性时,检测原型状态能提供一层额外的保障。我曾经在维护一个遗留项目时,发现有些核心对象被意外地修改了,后来才发现是某个第三方库在不经意间对原型进行了操作。如果当时有机制去检测并限制,也许就能避免很多麻烦。
这是一个非常好的问题,因为它触及到了JavaScript原型链的核心机制。简而言之,对一个原型对象执行密封操作(
Object.seal()
让我们来拆解一下:
当一个对象
obj
prop
obj
prop
obj
prop
null
现在,假设
MyClass.prototype
MyClass.prototype
MyClass.prototype
MyClass.prototype
但这些限制都只作用于
MyClass.prototype
new MyClass()
MyClass.prototype
举个例子:
function Base() {}
Base.prototype.baseMethod = function() { return "I'm from Base"; };
Object.seal(Base.prototype); // 密封 Base 的原型
function Derived() {}
Derived.prototype = Object.create(Base.prototype); // Derived 继承自 Base 的原型
Derived.prototype.constructor = Derived;
const instance = new Derived();
// 属性查找依然正常工作
console.log(instance.baseMethod()); // "I'm from Base"
// 实例对象自身仍然可以添加新属性
instance.myOwnProperty = "hello";
console.log(instance.myOwnProperty); // "hello"
// 实例对象自身仍然可以修改继承来的属性(如果该属性在实例自身上没有,会创建新的)
instance.baseMethod = function() { return "I'm overridden in instance"; };
console.log(instance.baseMethod()); // "I'm overridden in instance" (这是在实例上创建了一个新方法,而不是修改了 Base.prototype 上的方法)
console.log(Base.prototype.baseMethod()); // "I'm from Base" (Base.prototype 上的方法未变)你看,即使
Base.prototype
instance
baseMethod
Base.prototype
以上就是js如何检测原型是否被密封的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号