JavaScript原型链属性查找的核心规则是:先查对象自身,存在即返回,不继续向上;未找到则沿__proto__逐级向上查找至Object.prototype,最终null终止,返回undefined。

JavaScript 原型链决定属性查找顺序的核心规则是:**从当前对象开始,沿着 __proto__(即内部的 [[Prototype]])向上逐级查找,直到找到该属性或到达原型链顶端(null)为止。** 找到即返回,不会继续向上;未找到则返回 undefined。
属性查找严格遵循“自有属性优先”原则
每次访问对象的属性时,JS 引擎首先检查该对象自身是否拥有该属性(即在对象自身的属性键中存在),无论值是 undefined 还是其他值,只要键存在,就立即返回对应值,**不会继续查原型**。
- 例如:
obj.a = undefined,再访问obj.a会得到undefined,但不会去原型上找同名属性 - 用
hasOwnProperty()可判断是否为自有属性;in操作符则会查原型链
原型链是单向、线性的向上链接
每个对象(除 Object.create(null) 创建的对象外)都有一个隐式原型 __proto__,指向其构造函数的 prototype 对象。查找时依次访问:
-
obj→ 自身属性 -
obj.__proto__(即Constructor.prototype)→ 查找该对象 -
obj.__proto__.__proto__(即Object.prototype)→ 再往上 -
Object.prototype.__proto__ === null→ 终止查找
注意:Function.prototype.__proto__ 也指向 Object.prototype,所以函数对象同样能访问 .toString() 等方法。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
构造函数、prototype 和实例的关系直接影响链路
属性是否可被继承,取决于它被定义在哪个环节:
- 写在构造函数内(如
this.x = 1)→ 属于实例自有属性 - 写在
Constructor.prototype上(如Constructor.prototype.y = 2)→ 被所有实例通过原型链共享 - 使用
Object.setPrototypeOf(obj, proto)或class extends会显式改变原型链走向
例如:Array.prototype.map 存在于 Array.prototype,所以 [1,2].map 能查到;而 [1,2].push 同样来自同一原型,不是数组实例自己拥有的。
特殊情况:访问器属性和继承的 setter/getter
如果原型链上某层定义了 getter(如 Object.prototype.toString 是一个 getter),即使实例自身没有该属性,也会触发该 getter 并执行对应逻辑。
- 若子对象重写了同名 getter,则优先执行子对象的版本
- setter 同理:赋值时若自身无该属性且原型上有 setter,会调用原型上的 setter(而非在自身创建新属性)
- 可通过
Object.defineProperty(obj, 'prop', { value: ..., writable: true })显式控制行为

















