原型链简介

96 阅读3分钟

一、原型

1.什么是原型

在JS构造函数中有一个属性prototype,叫做原型,这是给程序员使用的。在JS实例对象中有一个属性_proto_,它也是原型, 这是供浏览器使用的,不是标准的属性。实例对象中的_proto_指向的是该实例对象的构造函数中的prototype, 构造函数中的prototype里面的属性或者方法,可以直接通过实例对象调用。

一般情况下,实例对象._proto_才能访问到构造函数中的proto的属性或者方法,即实例对象._proto_.xxx。因为_proto_不是 标准的属性,所以直接写成实例对象.xxx即可。原型是一个属性,而这个属性也是一个对象。

2.原型的作用

在构造函数中定义的属性和方法,当实例化对象的时候,实例对象中的属性和方法都是在自己的空间中存在的 ,如果是多个对象,这些属性和方法都会在单独的空间存在,浪费内存空间。所以,为了实现数据共享, 把想要节省空间的属性或者方法写在原型对象中,就能达成数据共享的目的,节省了内存空间。

3.原型的写法

  • 构造函数.prototype.属性 = value
  • 构造函数.prototype.方法 = value --->函数.prototype也是个对象,所以里面也会有_proto_
  • 实例对象.prototype ---> 实例对象中没有这个属性,只有_proto_

4.通过原型为内置对象添加方法或属性

系统的内置对象的属性或方法有时可能不能满足开发需求,所以可以通过原型的方式加入属性或者方法。 在添加完属性和方法之后,这个内置对象的实例对象就可以直接使用添加的属性或者方法

img1.png

此时我们可以在控制台接收到p1这个实例化对象执行sayHi方法的结果,如下图:

img2.png

因此我们在开发中可以将公共的常用方法封装在原型上,提升开发效率的同时减少内存空间

二、原型链

1.原型链是什么?

原型链是一种关系,是实例对象和原型对象之间的关系,这种关系是通过原型来联系的。

JavaScript对象有一个指向原型对象的链,当访问一个对象的属性时,它不仅仅在当前对象上搜寻,还会搜寻该对象的原型,以及该原型的原型,依次向上搜索,直到找到对应的属性或到达原型链的末尾。通俗一点讲就是:你在调用一个对象的属性或者方法时,它会顺着原型链依次向上查找直到底层,如果没有找到则会返回Undefined。

2.原型的指向

原型的指向是可以改变的,通过下面代码可以体会原型指向改变之后的结果:

img3.png

img4.png

通过结果我们可以知道当我们将原型的指向改变之后,之前定义在自身原型上的方法或者属性将找不到,此时改变指向之后的原型上的方法都可以调用。注意:如果我们在改变指向后再在此原型上添加方法,指向的这个原型对象(person)并不能使用当前对象上的原型(student)的属性或者方法

img5.png

img6.png

3.原型的最终指向

通过上方的案例我们可以知道,实例化对象上有_proto_原型,构造函数中有prototype原型,prototype也是一个对象,那么,prototype这个对象中应该也有_proto_,直到最后指向的_proto_是null。

所以一个实例对象的原型指向应该为:

实例化对象的_proto_ --> 实例化对象.protype --> 实例化.prototype._proto_ --> Object.prototype -->Object.prototype._proto_的值为Null。这就构成了一个完整的原型链。