JavaScript属性动态绑定本质是原型链实时查找机制——每次访问都从对象自身开始逐级向上搜索__proto__,原型的增删改立即影响所有实例,但赋值操作仅作用于实例自身。

JavaScript 中属性的动态绑定特性,本质是原型链查找机制在运行时实时生效的结果——不是复制值,而是每次访问都顺着 __proto__ 一层层向上找,只要原型上新增、修改或删除了属性,所有继承它的实例立刻“看到”变化。
属性访问永远走实时查找链
当你读取一个对象的属性(如 obj.name),JS 引擎不会缓存结果,也不会在创建时“快照”原型状态。它严格按以下顺序实时查找:
- 先检查对象自身是否有该属性(
hasOwnProperty为 true) - 没有就去
obj.__proto__(即构造函数的prototype)上找 - 还没找到,继续查
obj.__proto__.__proto__,直到到达null
这个过程每次访问都重新执行,所以原型上的改动会立即反映在所有实例上。
修改原型会影响已有实例
给原型添加或改写属性/方法,不需要重新创建实例,已存在的对象就能用:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
function Person() {}
const p1 = new Person();
console.log(p1.sayHi); // undefined
Person.prototype.sayHi = function() { return 'Hi!'; };
console.log(p1.sayHi()); // 'Hi!' —— 立刻可用
注意:这仅对“读取”生效;如果实例自身已有同名属性,则屏蔽原型上的,修改原型不会影响该实例的自有属性。
删除原型属性会触发回退查找
用 delete 删除原型上的属性后,查找会继续向上(比如到 Object.prototype),或最终返回 undefined:
Person.prototype.age = 25; console.log(p1.age); // 25 delete Person.prototype.age; console.log(p1.age); // undefined(不再命中)
但若 p1 自身有 age,delete Person.prototype.age 完全不影响 p1.age 的值——这是属性屏蔽(shadowing)的体现。
动态绑定不适用于赋值操作
关键区别:读取走原型链,但**直接赋值给实例属性(p1.name = 'Alice')永远只写在实例自身,不会修改原型**。这是避免意外污染共享原型的核心设计:
-
p1.name = 'Alice'→ 在p1上新建自有属性name -
p1.name = 'Alice'不会改变Person.prototype.name - 后续读取
p1.name优先返回自有值,屏蔽原型同名属性
想改原型上的值,必须显式操作原型:Person.prototype.name = 'Alice'。

















