JavaScript通过[[Get]]操作沿原型链查找属性:先查对象自身,再逐级通过__proto__向上查找至Object.prototype(其__proto__为null),未找到则返回undefined。

JavaScript 中顺着原型链查找属性与方法,是通过内部的 [[Get]] 操作自动完成的:当访问一个对象上不存在的属性或方法时,引擎会沿着 __proto__(即 Object.getPrototypeOf() 返回的对象)逐级向上查找,直到找到该属性,或到达原型链顶端(null)为止。
原型链查找的基本过程
每次读取对象的属性(如 obj.x),JS 引擎按以下顺序进行:
- 先检查对象自身是否拥有该属性(自有属性),有则直接返回值;
- 没有则检查其
[[Prototype]](即obj.__proto__)对象; - 在该原型对象上重复查找;
- 若一直未找到,最终查到
Object.prototype,它的__proto__是null,查找终止,返回undefined。
如何验证原型链上的属性来源
可以使用几个内置方法辅助判断属性在哪一层定义:
-
obj.hasOwnProperty('prop'):只检查对象自身,不查原型链; -
'prop' in obj:查自身 + 整条原型链; -
Object.prototype.hasOwnProperty.call(obj, 'prop'):更安全的自有属性检测(防对象重写hasOwnProperty); -
Object.getPrototypeOf(obj):获取当前对象的直接原型; -
Object.getOwnPropertyNames(obj):只列出对象自身的可枚举与不可枚举属性名(不含原型链)。
常见易混淆点
注意这些细节,避免误判查找行为:
立即学习“Java免费学习笔记(深入)”;
- 方法调用(如
obj.method())也走原型链查找,但this始终指向调用时的原始对象(不是定义方法的那个原型对象); - 设置属性(
obj.x = 1)**不会**修改原型上的同名属性,而是在对象自身创建新属性; - 只有 读取 属性时才沿原型链查找;写入/删除 都只作用于对象自身(除非属性是 setter 或有特殊描述符);
- 箭头函数没有自己的
this和prototype,不能作为构造函数,也不参与原型链继承。
手动模拟原型链查找(教学用)
下面是一个简化版的查找函数,帮助理解机制:
function get(obj, key) {
let current = obj;
while (current !== null) {
if (current.hasOwnProperty(key)) return current[key];
current = Object.getPrototypeOf(current);
}
return undefined;
}
// 使用示例:
const parent = { foo: 'from parent' };
const child = Object.create(parent);
console.log(get(child, 'foo')); // 'from parent'


















