返回

深入探索 JavaScript 原型和原型链,掌握面向对象编程的核心概念

前端

在 JavaScript 中,原型和原型链的概念对于理解面向对象编程 (OOP) 至关重要。原型是 JavaScript 对象的一个固有属性,它是一个指向创建该对象的构造函数的原型对象的指针。原型链则是由一连串原型对象组成的链条,它允许 JavaScript 对象访问其父对象(即原型对象)的属性和方法。

原型

原型(prototype)是一个 JavaScript 对象的固有属性,它是一个指向创建该对象的构造函数的原型对象的指针。每个 JavaScript 函数都具有一个 prototype 属性,而每个 JavaScript 对象都具有一个 [[Prototype]](也称为 proto)内部属性,该属性指向创建该对象的构造函数的原型对象。原型对象包含着该构造函数所创建的所有对象的共享属性和方法,这些共享属性和方法可以被该构造函数创建的所有实例继承。

原型链

原型链(prototype chain)是由一连串原型对象组成的链条,它允许 JavaScript 对象访问其父对象(即原型对象)的属性和方法。当一个 JavaScript 对象需要访问一个它自己没有的属性或方法时,它会沿着原型链向上查找,直到找到该属性或方法为止。这个查找过程被称为原型链查找(prototype chain lookup)。

原型链的查找过程类似于一个寻宝之旅。当一个 JavaScript 对象需要访问一个它自己没有的属性或方法时,它会首先检查自己的属性和方法。如果它在自己的属性和方法中找不到该属性或方法,它就会沿着原型链向上查找,查看其原型对象是否具有该属性或方法。如果在原型对象中找到了该属性或方法,那么它就会使用该属性或方法。如果在原型对象中也找不到该属性或方法,那么它就会继续沿着原型链向上查找,直到找到该属性或方法为止。

使用构造函数创建对象

在 JavaScript 中,可以使用构造函数来创建对象。构造函数是一个特殊的函数,它可以被用来创建新对象。当一个构造函数被调用时,它会创建一个新的对象,并且该对象将继承构造函数的原型对象的属性和方法。

例如,以下代码展示了如何使用构造函数创建一个新对象:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const person = new Person('John', 30);

console.log(person.name); // 'John'
console.log(person.age); // 30

在这个例子中,Person 是一个构造函数,它具有两个参数 nameage。当 Person 构造函数被调用时,它会创建一个新的对象 person,并且该对象将继承 Person 构造函数的原型对象的属性和方法。因此,person 对象具有 nameage 两个属性,它们的值分别为 'John' 和 30。

使用原型链实现继承

在 JavaScript 中,可以使用原型链来实现继承。继承是指一个对象可以从另一个对象继承属性和方法。在 JavaScript 中,子对象可以通过继承父对象(即原型对象)的属性和方法来实现继承。

例如,以下代码展示了如何使用原型链实现继承:

function Parent() {
  this.name = 'John';
}

Parent.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}`);
};

function Child() {
  this.age = 30;
}

Child.prototype = new Parent();

const child = new Child();

console.log(child.name); // 'John'
console.log(child.age); // 30
child.greet(); // 'Hello, my name is John'

在这个例子中,Parent 是父对象,Child 是子对象。Child 对象的原型对象 (Child.prototype) 被设置为 new Parent(),这意味着 Child 对象继承了 Parent 对象的属性和方法。因此,Child 对象具有 nameage 两个属性,它们的值分别为 'John' 和 30。Child 对象也继承了 Parent 对象的 greet() 方法,该方法可以在控制台中输出 Hello, my name is John

使用原型链实现多态性

在 JavaScript 中,可以使用原型链来实现多态性。多态性是指对象可以对相同的消息做出不同的响应。在 JavaScript 中,可以通过重写父对象(即原型对象)的方法来实现多态性。

例如,以下代码展示了如何使用原型链实现多态性:

function Animal() {}

Animal.prototype.speak = function() {
  console.log('Animal speaks');
};

function Dog() {}

Dog.prototype = new Animal();

Dog.prototype.speak = function() {
  console.log('Dog barks');
};

function Cat() {}

Cat.prototype = new Animal();

Cat.prototype.speak = function() {
  console.log('Cat meows');
};

const animal = new Animal();
const dog = new Dog();
const cat = new Cat();

animal.speak(); // 'Animal speaks'
dog.speak(); // 'Dog barks'
cat.speak(); // 'Cat meows'

在这个例子中,Animal 是父对象,DogCat 是子对象。Animal 对象具有一个 speak() 方法,该方法输出 Animal speaksDog 对象和 Cat 对象分别重写了 Animal 对象的 speak() 方法,分别输出 Dog barksCat meows。因此,当调用 animal.speak()dog.speak()cat.speak() 时,它们分别输出 Animal speaksDog barksCat meows