原型链(Prototype Chain)是JavaScript中面向对象编程的一个核心概念,它定义了对象之间的层次关系和属性查找机制。在JavaScript中,每个对象都有一个[[Prototype]]
属性(内部属性),这个属性指向其原型对象。当访问对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript引擎就会沿着原型链向上查找,直到找到该属性或方法或者到达原型链的末端(即Object.prototype
的原型是null
)。
原型链的组成:
-
每个对象都有原型 :当创建一个对象时,如果没有指定构造函数的
prototype
属性,那么该对象的原型默认是Object.prototype
。 -
构造函数的
prototype
属性 :每个函数都有一个prototype
属性,它是一个对象,这个对象的所有实例(通过这个函数创建的对象)都将继承它。 -
Object.prototype
:所有使用new Object()
或直接创建的对象(如字面量创建的对象)都会继承Object.prototype
。 -
原型链的顶端 :
Object.prototype
的原型是null
,标志着原型链的末端。
如何访问原型:
在JavaScript中,可以使用__proto__
(非标准,但广泛支持)或Object.getPrototypeOf()
(标准方法)来访问一个对象的原型。
原型链的查找过程:
当你尝试访问一个对象的属性或方法时,以下查找过程会发生:
- 首先检查对象自身是否包含该属性或方法。
- 如果对象自身没有该属性或方法,JavaScript引擎会沿着原型链向上查找该属性或方法。
- 如果找到了对应的属性或方法,就直接返回该值。
- 如果到达原型链的末端(
Object.prototype
)仍未找到,那么返回undefined
。
原型链与继承:
原型链也是JavaScript实现继承的一种方式。当你创建一个对象时,它会自动继承其原型对象的属性和方法。这种继承方式使得JavaScript中的类可以更轻量级,因为不需要每个子类都复制一份父类的代码,只需继承父类的原型即可。
示例:
javascript
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
return "Hello, my name is " + this.name;
};
var person = new Person("Alice");
// 通过原型链访问
console.log(person.sayHello()); // 输出: Hello, my name is Alice
console.log(person.__proto__ === Person.prototype); // 输出: true
console.log(Person.prototype.__proto__ === Object.prototype); // 输出: true
在这个例子中,person
对象继承自Person.prototype
,而Person.prototype
又继承自Object.prototype
。这使得person
可以访问sayHello
方法。