在 javascript 中,原型对象上定义只读访问器的核心是使用 object.defineproperty() 在 constructor.prototype 上仅声明 get 方法;这样实例读取时触发 getter,赋值则无效(非严格模式静默失败,严格模式报错),且该方式兼容 es5+、意图明确。

在 JavaScript 中,原型对象上定义只读访问器,核心是使用 Object.defineProperty() 为原型(如 Constructor.prototype)添加一个只有 get、没有 set 的访问器属性。这样所有实例通过该属性名读取时会触发 getter,但赋值操作无效(非严格模式静默失败,严格模式报错)。
直接在 prototype 上用 defineProperty 定义 get-only 访问器
这是最标准、兼容性好(ES5+)、明确表达“只读”意图的方式:
- 调用
Object.defineProperty(YourConstructor.prototype, 'propName', { get() { ... } }) - 不提供
set函数,就天然不可写 - 默认
configurable: false和enumerable: false,若需遍历或删除,显式设为true
示例:
复制代码function Person(name) {<br> this._name = name;<br>}<br><br>Object.defineProperty(Person.prototype, 'fullName', {<br> get() {<br> return this._name || 'Anonymous';<br> }<br>});<br><br>const p = new Person('Alice');<br>console.log(p.fullName); // 'Alice'<br>p.fullName = 'Bob'; // 无效,无副作用<br>console.log(p.fullName); // 仍为 'Alice'
在类语法中通过 prototype 链间接定义(不推荐直接操作)
ES6 类的 get 声明会自动挂载到类的 prototype 上,本质仍是访问器属性。但注意:不能在类体外对已存在的类原型用 get 语法追加——必须用 defineProperty。
- 正确方式:在类内部声明
get fullName() { ... },它会被自动添加到ClassName.prototype - 错误理解:“
class A { } A.prototype.get xxx = ...” 语法非法
避免常见误区
-
不要用
writable: false + value混搭访问器:数据属性(含value)和访问器属性(含get)互斥,混用会抛错 -
别依赖
configurable: false来“防改”:它只是防止删除或重定义,不阻止值变化;真正防写靠get无set或writable: false(用于数据属性) -
实例上同名属性会屏蔽原型访问器:如果某实例手动设置了
p.fullName = 'xxx',后续读取将不再走原型 getter,而是返回实例自有属性值——这不是“被修改”,而是覆盖
对比其他只读方案的适用场景
-
Object.freeze():冻结整个对象,适合配置对象等一次性常量结构,不适用于需动态计算的只读属性(如依赖this的fullName) -
static属性:属于类本身,不是原型链上的实例可访问属性,实例需通过this.constructor.STATIC_NAME间接访问 - 全大写命名约定(如
MAX_SIZE):仅语义提示,无运行时保护,不满足“强制只读”需求
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











