JavaScript原型链是对象查找属性和方法时沿[[Prototype]]隐式链接的路径,始于对象自身,逐级向上至null;它通过构造函数的prototype属性、Object.create等实现继承,影响属性访问、instanceof判断及共享引用类型属性。

JavaScript 原型链是对象查找属性和方法时遵循的一条隐式链接路径,它决定了一个对象“能访问什么”,是 JS 实现继承的核心机制。
原型链是怎么形成的?
每个对象内部都有一个隐藏属性 [[Prototype]](可通过 Object.getPrototypeOf() 或非标准的 __proto__ 访问),它指向该对象的原型对象。而原型对象本身也可能有 [[Prototype]],这样层层向上,直到最终指向 null,就构成了原型链。
函数对象还额外拥有 prototype 属性(显式对象),它会被用作以该函数为构造器创建出的实例的 [[Prototype]]。
- 普通对象:字面量
{}的原型是Object.prototype - 数组:字面量
[]的原型是Array.prototype,其上层是Object.prototype - 自定义构造函数:
new Foo()的原型是Foo.prototype
属性查找如何依赖原型链?
当你读取一个对象的属性(如 obj.a)时,JS 引擎会按以下顺序查找:
立即学习“Java免费学习笔记(深入)”;
- 先检查对象自身是否有该属性(自有属性)
- 没有则沿 [[Prototype]] 向上,在原型对象中查找
- 继续向上,直到找到或到达
null
这个过程就是“委托”——对象把找不到的属性请求,委托给它的原型处理。方法调用、in 操作符、hasOwnProperty 的行为都受此影响(注意:hasOwnProperty 只查自身,不走原型链)。
原型链如何实现继承?
JS 没有类继承的语法糖之前,所有继承都靠手动设置原型链来完成。例如:
function Animal(name) { this.name = name; }
Animal.prototype.speak = function() { console.log(this.name + ' makes a sound'); };
function Dog(name, breed) {
Animal.call(this, name); // 继承实例属性
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype); // 关键:让 Dog.prototype 链向 Animal.prototype
Dog.prototype.constructor = Dog; // 修复 constructor 指向
const dog = new Dog('Leo', 'Golden');
dog.speak(); // → 'Leo makes a sound'(从 Animal.prototype 找到)
ES6 的 class 和 extends 只是语法糖,底层仍是通过操作原型链实现继承。
常见陷阱与注意事项
原型链虽灵活,但也容易引发误解:
- 修改原型对象会影响所有继承它的实例(包括已创建的)
- 多个实例共享原型上的引用类型属性(如数组、对象),易造成意外数据污染
-
instanceof判断依赖原型链:判断左操作数的 [[Prototype]] 链中是否出现右操作数的prototype - 箭头函数没有自己的
prototype,不能用作构造函数
理解原型链不是为了手写继承代码,而是为了真正看懂 JS 对象行为、调试属性访问问题、合理使用 Object.create、Object.setPrototypeOf 等 API。











