javascript对象属性查找本质是沿__proto__原型链向上搜索,从自身开始逐级访问__proto__直至null;原型链由[[prototype]]内部属性构建,函数的prototype决定实例的__proto__指向。

JavaScript 中对象属性的向上查找,本质是沿着 __proto__ 链(即原型链)逐级向上去找,直到找到该属性,或到达原型链末端(null)为止。
原型链是怎么形成的
每个对象都有一个内部属性 [[Prototype]](可通过 obj.__proto__ 或 Object.getPrototypeOf(obj) 访问),它指向该对象的原型对象。函数对象还有 prototype 属性,用于指定以它为构造函数创建出的实例的 __proto__ 值。
- 普通对象字面量(如
{})的__proto__指向Object.prototype -
Array实例的__proto__指向Array.prototype,而Array.prototype.__proto__又指向Object.prototype -
Object.prototype.__proto__是null,代表原型链终点
属性访问时的查找过程
当你写 obj.x,JS 引擎会:
- 先在
obj自身属性中查找x(自有属性,不包括继承来的) - 没找到,就去
obj.__proto__对象上找 - 还没找到,继续查
obj.__proto__.__proto__,依此类推 - 直到某一级找到了,返回值;或者最终到达
null,报undefined
这个过程对 . 和 [] 访问都适用,也适用于方法调用(因为方法也是属性)。
关键细节和常见误区
-
for...in会遍历自身 + 原型链上所有可枚举属性;而Object.keys()只返回自身可枚举属性 -
hasOwnProperty()判断的是“是否为自有属性”,不走原型链 - 修改原型对象上的属性,会影响所有从它继承的对象(除非子对象自己定义了同名属性,会屏蔽原型上的)
- 箭头函数没有
prototype,不能作为构造函数,也没有自己的__proto__链式继承逻辑(它的this是词法绑定的)
手动模拟一次查找(辅助理解)
你可以用下面这个简单函数体会查找逻辑:
function getProperty(obj, key) {
let current = obj;
while (current !== null) {
if (current.hasOwnProperty(key)) return current[key];
current = Object.getPrototypeOf(current);
}
return undefined;
}
// 用法:getProperty([1,2], 'push') → 返回 Array.prototype.push 函数
这和 JS 引擎内部做的查找逻辑一致,只是更显式。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











