(JavaScript)对原型、原型链的理解

1,858 阅读4分钟

通过类比形象的介绍

  1. 构造函数(Constructors)和实例(Instances)

    • 想象你要建造一座房子,你设计了一个房子的蓝图,这个蓝图就是构造函数。构造函数定义了房子的基本结构和属性。
    • 当你实际建造房子时,你基于蓝图创建了一个具体的房子,这个具体的房子就是一个实例。
  2. 原型对象(Prototype Object)

    • 在JavaScript中,每个构造函数都有一个特殊的属性叫做"prototype",你可以把它看作是房子蓝图的一个附属手册,包含了所有房子共享的特性,比如门、窗户、屋顶等。
    • 实例对象可以访问原型对象的内容,就像建造的房子可以查阅手册以了解如何使用窗户或门等。
  3. 原型链(Prototype Chain)

    • 当你要查找某个特定的属性或方法,而这个属性或方法在当前实例中不存在,JavaScript会自动去构造函数的原型对象中查找。这就像你在已建造的房子上找不到某个东西,然后去构造函数(蓝图)的说明书中查找。
  4. 继承(Inheritance)

    • JavaScript的原型链允许对象之间共享属性和方法,就像建造多座房子时,它们可以共享相同的蓝图,这可以节省内存和提高效率。
  5. 示例

    • 假设你有一个构造函数House,它有一个原型对象,定义了所有房子共享的方法,比如openDoorcloseWindow
    • 你创建了两个房子实例,myHouseyourHouse
    • 如果你调用myHouse.openDoor(),JavaScript会首先在myHouse实例中查找,找到了就执行;如果没有找到,它会继续查找House构造函数的原型,找到并执行。
    • 同样,如果你调用yourHouse.closeWindow(),JavaScript会在yourHouse中找到,因为这个方法在构造函数原型中。

这个类比帮助理解JavaScript中原型和原型链的概念,其中构造函数充当蓝图,实例是具体的建筑物,原型是蓝图的使用说明书,原型链允许属性和方法的共享,就像多座房子可以共享相同的蓝图。

  • 蓝图对应构造函数,它定义了如何创建对象实例。
  • 原型对应使用手册,它包含了对象实例共享的属性和方法的描述。

蓝图(构造函数)用于创建对象,而使用手册(原型对象)包含了对象实例可以共享的属性和方法,就像房子的蓝图告诉您如何建造房子,而使用手册告诉您如何使用房子的不同部分。

具体的介绍

原型(Prototype):

  1. 对象和原型关系:在JavaScript中,几乎所有的对象都有一个关联的原型。对象可以继承原型上的属性和方法。

  2. 对象字面量:当你创建一个对象时,可以使用对象字面量来定义它,例如:

const myObject = { key: 'value' };
  1. 原型对象:每个对象都有一个原型对象,你可以通过Object.getPrototypeOf()或者对象的__proto__属性来访问。例如:
const prototypeOfMyObject = Object.getPrototypeOf(myObject);
  1. 构造函数和原型:构造函数是一种特殊的函数,用于创建对象。通过构造函数创建的对象会自动关联到构造函数的原型。例如:
function Person(name) {
  this.name = name;
}

const person1 = new Person('Alice');
  1. 原型属性和方法:可以在原型对象上定义属性和方法,这些属性和方法将被从原型继承到实例对象。例如:
Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
}

原型链(Prototype Chain):

  1. 原型链的概念:原型链是一种对象之间的连接,用于查找属性和方法。每个对象都有一个原型,而原型本身也可以有自己的原型,从而形成一个链式结构。
  2. 属性和方法查找:当你试图访问一个对象上的属性或方法时,JavaScript引擎首先查找对象本身,然后在原型上查找,如果找不到就继续向上查找原型的原型,直到找到或者达到对象原型链的顶端。
  3. 原型链的终点:原型链的终点是Object.prototype,它是JavaScript中所有对象的顶层原型。Object.prototype上包含一些通用方法,例如toStringhasOwnProperty

由于 Object 是构造函数,原型链终点 Object.prototype.__proto__

Object.prototype.__proto__=== null // true,所以,原型链

的终点是 null。原型链上的所有原型都是对象,所有的对象最终都

是由 Object 构造的,而 Object.prototype 的下一级是

Object.prototype.__proto__

  1. 继承属性和方法:当一个对象通过原型链继承属性和方法时,它可以访问原型对象上定义的属性和方法,这实现了对象之间的继承关系。
function Animal(name) {
  this.name = name;
}

Animal.prototype.sayName = function() {
  console.log(`My name is ${this.name}`);
}

function Dog(name, breed) {
  Animal.call(this, name);
  this.breed = breed;
}

Dog.prototype = Object.create(Animal.prototype);

const myDog = new Dog('Buddy', 'Golden Retriever');
myDog.sayName(); // 继承自Animal的方法

上面的示例中,myDog对象继承了Animal的原型上的sayName方法,这是通过原型链实现的。

原型和原型链是JavaScript中面向对象编程的核心概念,它们使对象之间的关系和继承变得更加灵活和强大。

特点

JavaScript 对象是通过引用来传递的,创建的每个新对象实体中并没有一份属于自己的原型副本。当修改原型时,与之相关的对象也会继承这一改变。