Hi,我是布兰妮甜 !JavaScript是一门基于原型(prototype)的语言,其独特的继承机制——原型链(Prototype Chain),使得对象可以共享属性和方法,从而实现了面向对象编程中的代码复用。理解原型链的工作原理和如何实现继承是每个JavaScript开发者必备的知识。本文将深入探讨
原型链
的概念、工作方式及其在继承
中的应用。
文章目录
一、原型链基础
1. 每个对象都有一个内部链接[[Prototype]]
在JavaScript中,除了null
之外的所有对象都拥有一个内部属性[[Prototype]]
,它指向另一个对象,这个被引用的对象就是我们所说的“原型”。当尝试访问一个对象的属性时,如果该对象本身没有这个属性,JavaScript引擎会沿着[[Prototype]]
链向上查找,直到找到该属性或到达链的末端(即null
)。
const obj = {
};
console.log(obj.__proto__); // 输出: Object.prototype
2. Object.prototype是所有原型链的终点
Object.prototype
是原型链的顶端,它是所有对象的最终原型。这意味着即使是一个空对象也会继承自Object.prototype
上的方法,如toString()
、hasOwnProperty()
等。
const obj = {
};
console.log(obj.toString()); // 输出: [object Object]
3. 使用constructor属性
每个对象的原型都有一个constructor
属性,它指向创建该对象实例的构造函数。这有助于确定对象是由哪个构造函数创建的。
function Person(name) {
this.name = name;
}
const alice = new Person('Alice');
console.log(alice.constructor === Person); // 输出: true
4. instanceof操作符
instanceof
用于检查一个对象是否为某个构造函数的实例。它通过遍历对象的原型链来判断是否存在指定构造函数的原型。
function Animal() {
}
const dog = new Animal();
console.log(dog instanceof Animal); // 输出: true
console.log(dog instanceof Object); // 输出: true
二、原型链的工作原理
1. 属性查找
当访问一个对象的属性时,JavaScript引擎首先检查该对象自身是否有此属性。如果没有,则沿[[Prototype]]
链向上查找,直到找到该属性或到达链的末端。如果在整个链上都没有找到该属性,则返回undefined
。
const animal = {
type: 'Animal'
};
const dog = Object.create(animal);
dog.type = 'Dog';
console.log(dog.type); // 输出: Dog (优先使用自身属性)
delete dog.type;
console.log(dog.type); // 输出: Animal (从原型链继承)
2. 方法共享
原型链允许对象共享来自原型的方法,这样多个实例可以共享同一份方法定义,节省内存空间。
function Animal() {
}
Animal.prototype.makeSound = function() {
console.log(`${
this.name} makes a sound.`);
};
const cat = new Animal();
cat.name = 'Whiskers';
cat.makeSound(); // 输出: Whiskers makes a sound.
3. 继承层次结构
通过设置构造函数的prototype
属性,可以建立复杂的继承层次结构。子类不仅继承父类的属性和方法,还可以扩展自己的功能。
function Animal(name) {
this.name