原型链(Prototype Chain) 是 JavaScript 中实现继承的核心机制。每个对象都有一个内部属性
[[Prototype]]
(可以通过 __proto__
访问),指向其原型对象。每个对象都有一个原型, 原型本身也是一个对象,因此它也有自己的原型 。通过原型链,对象可以访问其原型对象的属性和方法。以下是原型链的详细说明:
获取原型的方法
方法 | 说明 |
---|---|
obj.__proto__ | 非标准方法,直接访问对象的原型。 |
Object.getPrototypeOf(obj) | 标准方法,推荐使用。 |
Object.prototype.isPrototypeOf(obj) | 检查对象是否在原型链上。 |
obj.constructor.prototype | 通过构造函数获取原型。 |
1. 原型对象
-
每个函数都有一个
prototype
属性,指向一个对象(称为原型对象)。 -
当使用
new
关键字创建实例时,实例的__proto__
会指向构造函数的prototype
。
示例
function Person(name) {
this.name = name;
}
// 在原型对象上添加方法
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
};
const person1 = new Person('Alice');
person1.sayHello(); // 输出: Hello, my name is Alice
-
person1.__proto__
指向Person.prototype
。 -
Person.prototype.constructor
指向Person
函数。
2. 原型链
-
当访问对象的属性或方法时,JavaScript 会先在对象自身查找,如果找不到,则沿着原型链向上查找,直到找到或到达原型链的顶端(
null
)。 -
原型链的顶端是
Object.prototype
,其__proto__
为null
。
示例
console.log(person1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true
3. 继承
通过原型链,可以实现对象之间的继承。
(1)构造函数继承
function Parent(name) {
this.name = name;
}
Parent.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
};
function Child(name, age) {
Parent.call(this, name); // 调用父类构造函数
this.age = age;
}
// 设置原型链
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
const child = new Child('Bob', 10);
child.sayHello(); // 输出: Hello, my name is Bob
(2)ES6 类继承
class Parent {
constructor(name) {
this.name = name;
}
sayHello() {
console.log(`Hello, my name is ${this.name}`);
}
}
class Child extends Parent {
constructor(name, age) {
super(name); // 调用父类构造函数
this.age = age;
}
}
const child = new Child('Bob', 10);
child.sayHello(); // 输出: Hello, my name is Bob
4. 原型链的查找过程
当访问对象的属性或方法时,JavaScript 会按照以下顺序查找:
-
在对象自身查找。
-
如果找不到,沿着
__proto__
向上查找,直到找到或到达null
。
示例
const obj = { a: 1 };
console.log(obj.toString()); // 输出: [object Object]
-
obj
自身没有toString
方法。 -
查找
obj.__proto__
(即Object.prototype
),找到toString
方法。
5. 修改原型链
可以通过修改 __proto__
或 prototype
来改变原型链。
示例
const parent = { name: 'Parent' };
const child = { age: 10 };
// 设置 child 的原型为 parent
child.__proto__ = parent;
console.log(child.name); // 输出: Parent