JavaScript中的原型对象(Prototype Object)是JavaScript面向对象编程中的一个核心概念。在JavaScript中,几乎所有的对象都有一个与之关联的原型对象(除了null
和undefined
)。这个原型对象自身也可以是一个对象,并且也有它自己的原型,这样就形成了一个原型链(Prototype Chain)。
原型对象的定义
原型对象:每个函数都有一个特殊的属性
prototype
,这个属性是一个对象,被称为原型对象。通过这个原型对象,我们可以为该函数创建的所有实例(即对象)添加共享的属性和方法。这些属性和方法不需要在每个实例上单独定义,从而节省了内存并促进了代码的重用。实例的
__proto__
属性(注意:__proto__
是一个非标准但广泛使用的属性,用于访问对象的原型对象。标准的方法是使用Object.getPrototypeOf(obj)
):每个通过构造函数(或其他方式)创建的对象都有一个内部链接到其原型对象的引用。在大多数现代JavaScript环境中,这个链接可以通过__proto__
属性访问,但更推荐使用Object.getPrototypeOf(obj)
方法,因为它更标准且更可靠。
原型对象的作用
共享属性和方法:原型对象允许你将属性和方法定义在构造函数的原型上,这样所有通过该构造函数创建的实例都可以共享这些属性和方法,而不是每个实例都单独拥有一份拷贝。
实现继承:通过原型链,JavaScript实现了基于原型的继承。一个对象的原型可以指向另一个对象的实例,从而继承该实例的属性和方法。这种继承机制与基于类的继承(如Java或C++中的继承)不同,但它同样强大且灵活。
查找属性:当访问一个对象的属性时,如果该对象本身没有这个属性,JavaScript会沿着原型链向上查找,直到找到该属性或到达原型链的顶端(
Object.prototype
的原型是null
)。
示例
function Person(name, age) {
this.name = name;
this.age = age;
}
// 在Person的原型上添加一个方法
Person.prototype.greet = function() {
console.log(`Hello, my name is ${
this.name} and I am ${
this.age} years old.`);
};
const person1 = new Person('Alice', 30);
const person2 = new Person('Bob', 25);
// person1和person2都继承了Person.prototype上的greet方法
person1.greet(); // Hello, my name is Alice and I am 30 years old.
person2.greet(); // Hello, my name is Bob and I am 25 years old.
// 检查原型链
console.log(person1.__proto__ === Person.prototype); // true,但推荐使用Object.getPrototypeOf(person1) === Person.prototype
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true,原型链的顶端
在这个示例中,Person
函数的原型对象上定义了一个greet
方法,然后创建了两个Person
的实例person1
和person2
。这两个实例都继承了Person.prototype
上的greet
方法,因此它们都可以调用这个方法。