在 JavaScript 中,原型(Prototype)和原型链(Prototype Chain)是实现继承和对象属性查找的重要机制。它们允许对象共享方法和属性,从而提高代码的复用性。
1. 原型(Prototype)
每一个 JavaScript 对象都有一个属性叫做 __proto__,它指向该对象的原型(即构造函数的 prototype 属性)。原型对象也是一个对象,通常包含了构造函数的共享方法和属性。
- 对象的原型由构造函数的
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"
在上面的例子中,Person 的实例 person1 通过其原型 Person.prototype 继承了 sayHello 方法。
2. 原型链(Prototype Chain)
原型链是 JavaScript 中用来查找对象属性和方法的机制。当访问一个对象的属性时,首先会检查对象本身是否有该属性。如果没有,JavaScript 会在该对象的原型上查找。如果原型上也没有,查找会继续沿着原型链向上进行,直到达到 null 为止。每个对象的原型又有自己的原型,这样形成一个链条,直到 Object.prototype 为止。
原型链的查找过程如下:
- 如果对象本身有该属性或方法,直接返回。
- 如果对象本身没有,查找对象的
__proto__,即对象的原型。 - 如果原型上也没有,继续查找原型的
__proto__,直到Object.prototype。 - 如果
Object.prototype上也没有该属性或方法,最终返回undefined。
例如:
const obj = {
name: 'John'
};
const person = Object.create(obj);
person.age = 30;
console.log(person.name); // 输出 "John" 来自 obj
console.log(person.age); // 输出 30 来自 person
在这个例子中,person 对象通过 Object.create(obj) 创建,它继承了 obj 的原型。因此当我们访问 person.name 时,JavaScript 会先检查 person 本身没有 name 属性,然后查找 obj,发现 name 存在,最后返回 "John"。
总结
- 原型(Prototype) 是每个对象都拥有的属性,指向该对象的构造函数的
prototype对象,通常存放共享的方法和属性。 - 原型链(Prototype Chain) 是属性查找的链式结构,JavaScript 通过该链来查找对象的属性和方法,直到找到为止,或者到达链的尽头
Object.prototype。
原型和原型链是 JavaScript 继承机制的基础,它允许对象共享功能和实现继承。