通过类比形象的介绍
-
构造函数(Constructors)和实例(Instances) :
- 想象你要建造一座房子,你设计了一个房子的蓝图,这个蓝图就是构造函数。构造函数定义了房子的基本结构和属性。
- 当你实际建造房子时,你基于蓝图创建了一个具体的房子,这个具体的房子就是一个实例。
-
原型对象(Prototype Object) :
- 在JavaScript中,每个构造函数都有一个特殊的属性叫做"prototype",你可以把它看作是房子蓝图的一个附属手册,包含了所有房子共享的特性,比如门、窗户、屋顶等。
- 实例对象可以访问原型对象的内容,就像建造的房子可以查阅手册以了解如何使用窗户或门等。
-
原型链(Prototype Chain) :
- 当你要查找某个特定的属性或方法,而这个属性或方法在当前实例中不存在,JavaScript会自动去构造函数的原型对象中查找。这就像你在已建造的房子上找不到某个东西,然后去构造函数(蓝图)的说明书中查找。
-
继承(Inheritance) :
- JavaScript的原型链允许对象之间共享属性和方法,就像建造多座房子时,它们可以共享相同的蓝图,这可以节省内存和提高效率。
-
示例:
- 假设你有一个构造函数
House
,它有一个原型对象,定义了所有房子共享的方法,比如openDoor
和closeWindow
。 - 你创建了两个房子实例,
myHouse
和yourHouse
。 - 如果你调用
myHouse.openDoor()
,JavaScript会首先在myHouse
实例中查找,找到了就执行;如果没有找到,它会继续查找House
构造函数的原型,找到并执行。 - 同样,如果你调用
yourHouse.closeWindow()
,JavaScript会在yourHouse
中找到,因为这个方法在构造函数原型中。
- 假设你有一个构造函数
这个类比帮助理解JavaScript中原型和原型链的概念,其中构造函数充当蓝图,实例是具体的建筑物,原型是蓝图的使用说明书,原型链允许属性和方法的共享,就像多座房子可以共享相同的蓝图。
- 蓝图对应构造函数,它定义了如何创建对象实例。
- 原型对应使用手册,它包含了对象实例共享的属性和方法的描述。
蓝图(构造函数)用于创建对象,而使用手册(原型对象)包含了对象实例可以共享的属性和方法,就像房子的蓝图告诉您如何建造房子,而使用手册告诉您如何使用房子的不同部分。
具体的介绍
原型(Prototype):
-
对象和原型关系:在JavaScript中,几乎所有的对象都有一个关联的原型。对象可以继承原型上的属性和方法。
-
对象字面量:当你创建一个对象时,可以使用对象字面量来定义它,例如:
js
const myObject = { key: 'value' };
- 原型对象 :每个对象都有一个原型对象,你可以通过
Object.getPrototypeOf()
或者对象的__proto__
属性来访问。例如:
js
const prototypeOfMyObject = Object.getPrototypeOf(myObject);
- 构造函数和原型 :构造函数是一种特殊的函数,用于创建对象。通过构造函数创建的对象会自动关联到构造函数的原型。例如:
js
function Person(name) {
this.name = name;
}
const person1 = new Person('Alice');
- 原型属性和方法:可以在原型对象上定义属性和方法,这些属性和方法将被从原型继承到实例对象。例如:
js
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
}
原型链(Prototype Chain):
- 原型链的概念:原型链是一种对象之间的连接,用于查找属性和方法。每个对象都有一个原型,而原型本身也可以有自己的原型,从而形成一个链式结构。
- 属性和方法查找:当你试图访问一个对象上的属性或方法时,JavaScript引擎首先查找对象本身,然后在原型上查找,如果找不到就继续向上查找原型的原型,直到找到或者达到对象原型链的顶端。
- 原型链的终点 :原型链的终点是Object.prototype ,它是JavaScript中所有对象的顶层原型。Object.prototype上包含一些通用方法,例如
toString
和hasOwnProperty
。 - 继承属性和方法:当一个对象通过原型链继承属性和方法时,它可以访问原型对象上定义的属性和方法,这实现了对象之间的继承关系。
js
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 对象是通过引用来传递的,创建的每个新对象实体中并没有一份属于自己的原型副本。当修改原型时,与之相关的对象也会继承这一改变。