什么是 JavaScript 中的原型链?
JavaScript 中的原型链是一种用于实现对象继承的核心机制,通过链接 prototype 对象形成链式结构。
原型链 ( Prototype Chain ) 是 JavaScript 中实现对象继承的核心机制,基于对象之间的链接(原型对象)形成一个链式结构。当访问一个对象属性或方法时,若该对象自身未定义, JavaScript 引擎会沿原型链逐级向上查找,直到找到属性或到达链末端 ( null )。
以下是详细解释:
- 定义与基本概念:
JavaScript 中每个对象都有内部属性 ( [[Prototype]] ),指向其原型对象。原型本身也是一个对象,可能拥有自己的原型,构成一条“原型链”,终结点为 null。此机制支持继承和属性共享,使 JavaScript 成为基于原型的语言。 - 工作原理:
- 属性查找流程:访问属性时先在对象自身搜索;如未找到,沿着其原型链查找上级原型对象 ( 例如通过
__proto__
或Object.getPrototypeOf()
获取的链接 ),递归向上直至找到属性或抵达 null ( 此时返回 undefined )。 - 作用范围:如方法访问或属性查询都遵循此过程,确保动态性,例如自定义方法通过原型链覆盖原生方法。
- 属性查找流程:访问属性时先在对象自身搜索;如未找到,沿着其原型链查找上级原型对象 ( 例如通过
-
函数的角色与示例:
构造函数定义了.prototype
对象,包含所有实例共享的属性和方法。通过new
创建对象时,其实例的__proto__
指向构造函数的.prototype
,完成继承。
例如:function Person(name) { this.name = name; // 实例属性 } Person.prototype.greet = function() { // 共享方法 console.log("Hello, I am " + this.name); }; const person = new Person("Alice"); console.log(person.hasOwnProperty("name")); // true console.log(person.hasOwnProperty("greet")); // false, 方法不在对象上, 来自 Person.prototype console.log(person.greet()); // Hello, I am Alice
在上面代码中,
person.greet()
成功调用是因为沿着链查找:person
→Person.prototype
→Object.prototype
。若无此机制,会无法调用不存在的属性。 - 继承实现:
- 设置子类型构造函数的
.prototype
为父类型实例,如 ES5:Child.prototype = Object.create(Parent.prototype);
- 在 ES6 中使用
class
语法简化但底层依然基于原型链:
class Animal { constructor(species) { this.species = species; } describe() { console.log("Species: " + this.species); } } class Dog extends Animal { constructor(name) { super("Dog"); // 调用父构造函数 this.name = name; } } const dog = new Dog("Buddy"); dog.describe(); // Species: Dog, 通过原型链找到 Animal.prototype.describe
- 设置子类型构造函数的
- 重要性:
原型链提升代码复用率和性能:- 避免冗余方法定义在构造函数中,节省内存。
- 实现动态和灵活继承方式 ( 如原型链共享更改会反映在所有实例 )。
- 潜在问题与注意:
使用非标准__proto__
不推荐 ( 可使用Object.getPrototypeOf()
/Object.setPrototypeOf()
)。过度修改原型链可能导致逻辑错误。
此机制是 JavaScript 基础组成部分,帮助理解语言本质如封装、继承和多态。