javascript原型链实现属性动态扩展与覆盖的核心机制是:属性访问沿[[prototype]]链向上查找,而赋值默认写入实例自身;在prototype上添加属性即动态扩展所有实例,在实例赋同名属性即覆盖原型值,且可通过hasownproperty和object.defineproperty精确控制。

JavaScript 中通过原型链实现属性的动态扩展与覆盖,核心在于理解对象的内部属性 [[Prototype]](即 __proto__)和构造函数的 prototype 对象之间的关系。属性访问时会沿原型链向上查找,而赋值行为则默认作用于当前对象自身——这正是“扩展”与“覆盖”的底层机制。
动态扩展:在原型上添加新属性或方法
向构造函数的 prototype 添加属性,所有已存在和未来创建的实例都能立即访问到它,无需修改实例本身。
- 新增方法:
Person.prototype.sayHello = function() { return `Hi, I'm ${this.name}` },所有new Person()实例立刻拥有sayHello方法 - 新增数据属性:
Array.prototype.last = function() { return this[this.length - 1] },之后所有数组都能调用[1,2,3].last() - 注意:扩展原生原型(如
Array.prototype)需谨慎,避免命名冲突或破坏标准行为
属性覆盖:实例属性优先于原型属性
当给实例直接赋值一个与原型同名的属性时,该属性会被写入实例自身,后续访问将不再查原型——这就是“覆盖”。原型上的原始值不受影响,其他实例仍使用原型值。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
const p = new Person('Alice');→p.name查找路径:实例无name→ 找到Person.prototype.name -
p.name = 'Bob';→ 在p对象上创建自有属性name,覆盖了原型链查找 -
console.log(p.name); // 'Bob';console.log(Object.getPrototypeOf(p).name); // 原来的值(如 'default')
检查与控制覆盖行为:hasOwnProperty 与 Object.defineProperty
判断属性来源、防止意外覆盖或实现只读/不可枚举等高级控制,需借助属性描述符。
-
p.hasOwnProperty('name')返回true表示是实例自有属性,false表示来自原型 - 用
Object.defineProperty设置原型属性为writable: false,可阻止实例直接赋值覆盖(但可通过Object.defineProperty(p, 'name', ...)显式定义) - 设置
enumerable: false可让原型方法不被for...in遍历到,保持接口干净
继承链中的多级覆盖与扩展
原型链可多层嵌套(如 B.prototype.__proto__ === A.prototype),覆盖和扩展可在任意层级发生,查找顺序始终是从实例开始逐级向上。
- 子类方法中用
super.method()(ES6 类语法)或A.prototype.method.call(this)显式调用父级实现 - 重写父类方法时,若想保留原有逻辑,需手动调用;否则就是完全替换
- 动态修改中间原型(如
A.prototype.foo = ...)会影响所有继承自A的子类实例,包括已创建的
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










