原型、原型链

343 阅读3分钟

原型

每一个函数在创建时,都会被赋予一个prototype属性,它指向函数的原型对象,这个原型对象,可以包含所有由这个函数创建的所有实例共享的属性和函数。

这样就解决了,通过构造函数创建实例时,在不同的实例中重复创建的问题。

构造函数、原型对象、实例之间的关系

在一个函数创建时,都会被赋予一个prototype属性。

默认情况下,所有的原型对象都会增加一个constructor属性,指向prototype这个函数。

实例有一个__proto__属性,指向构造函数的原型对象,

实例与构造函数的原型对象有直接的联系,但实例与构造函数没有直接的联系。

实例属性的读取顺序

当我们读取实例的属性时,是一个搜索的过程。

它会在实例本身中找这个属性

  • 如果找到了,就返回
  • 如果没找到,沿着这个实例的原型对象寻找,在原型对象中找到了,就返回该属性

原型有什么用

获得一个属性的value时,优先在自己的对象中查找,如果找不到,就去原型对象中查找

一个构造函数,是有两部分组成的。

一部分是它的属性,在创建实例的时候,属性是定制化的,每个对象可能有自己独特的属性

一部分是它的函数,函数完成一定的功能,具有通用性

如果把函数直接写在函数内部,,每new一个对象,构造函数里面的函数对象就会都被创建一次。这样是很费内存的

如果把函数这样的通用信息保存在函数的原型中,就不会产生这样的问题了

如何获取原型

Object.getPrototypeOf

原型链

构造函数、原型对象、实例之间存在这样的关系:每个构造函数有一个原型对象,原型对象有一个属性指回构造函数,而实例有一个内部指针指向原型对象。

如果原型对象是另一个类型的实例,意味着原型对象有一个内部指针指向另一个原型,相应的,这另一个原型内部也有一个指针指向另一个构造函数。这样,实例和原型对象之间就构造了一条原型链(由__proto__属性连接而成的链路构成了原型链)。

每个原型对象有自己的__proto__属性,这个属性指向某一个原型对象,就这样形成了一条原型链

原型链相关知识

  • 由于原型链的存在,属性查找会是沿着整个原型链的进行查找,如果查找路径过长,对性能影响大
  • 对象的属性查找会沿着整个原型链,那么,对象的属性就可以分为两种:实例自身属性、原型链继承的属性。hasOwnProperty()函数,在属性为自身属性时return true,在属性为原型链继承属性时return false
  • JavaScript中内置构造函数,如String()、Number()、Date()等,他们的__proto__都指向Function.prototype

原型链的终点

由上图可见,原型链的终点是Object原型对象的__proto__属性,指向null