javascript原型链通过__proto__逐级向上查找属性,始于对象自身,止于object.prototype.__proto__ === null;new构造函数时实例的__proto__指向其prototype,属性读取沿链搜索,赋值则仅作用于对象自身。

JavaScript 中通过原型链查找继承属性,本质是沿着对象的 __proto__(或 Object.getPrototypeOf())向上逐级搜索,直到找到目标属性或到达原型链顶端(null)。
原型链是怎么形成的
每个对象都有一个内部属性 [[Prototype]](可通过 __proto__ 访问),它指向该对象的原型对象。函数对象还有 prototype 属性,用于指定其**实例对象**的 [[Prototype]]。
- 用
new Foo()创建实例时,实例的__proto__会自动指向Foo.prototype -
Foo.prototype默认有一个constructor属性,且它的__proto__指向Object.prototype -
Object.prototype.__proto__ === null,这是原型链终点
属性查找的具体过程
当你访问 obj.prop 时,JS 引擎按以下顺序查找:
- 先检查
obj自身是否拥有prop(hasOwnProperty为true) - 如果没有,就去
obj.__proto__上找 - 还没找到,继续查
obj.__proto__.__proto__,依此类推 - 直到某一级原型有该属性,或查到
null为止(此时返回undefined)
怎么验证原型链和属性来源
可以用几个实用方法观察查找路径:
-
obj.hasOwnProperty('prop'):判断是否为自有属性 -
prop in obj:判断是否在自身或原型链上存在(包括继承的) -
Object.getPrototypeOf(obj):获取直接原型 -
Object.getOwnPropertyNames(obj):只列出对象自身的可枚举/不可枚举属性名
例如:
function Animal() {}
Animal.prototype.eat = function() { return 'eating'; };
function Dog() {}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.bark = function() { return 'woof'; };
const dog = new Dog();
console.log(dog.bark()); // 'woof' → 自身原型上有
console.log(dog.eat()); // 'eating' → 沿着 Dog.prototype → Animal.prototype 找到
console.log(dog.toString()); // '[object Object]' → 继承自 Object.prototype
注意:赋值和查找行为不同
读取属性走原型链,但**赋值默认只写在对象自身**(不会修改原型):
-
dog.eat = function() {...}→ 在dog上新增自有方法,不改变Animal.prototype.eat - 想改原型上的属性,必须显式操作原型对象:
Dog.prototype.eat = ...
这也是为什么重写继承方法时,常需手动修复 constructor:
Dog.prototype.constructor = Dog;
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











