image.png

原型

JavaScript 常被描述为一种基于原型的语言——每个对象拥有一个原型对象
当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾
准确地说,这些属性和方法定义在Object的构造器函数(constructor functions)之上的prototype属性上,而非实例对象本身
函数可以有属性。每个函数都有一个特殊的属性叫作原型prototype

原型对象有一个自有属性constructor,这个属性指向该函数,如下图关系展示
image.png
JavaScript万物都是对象,对象中都包含了一个”prototype”内部属性,这个属性所对应的就是该对象的原型

如:Foo.prototype 就是一个原型对象

原型对象的用途是为每个实例对象存储共享的方法和属性,它仅仅是一个普通对象而已。并且所有的实例是共享同一个原型对象,因此有别于实例方法或属性,原型对象仅有一份。

关系:

  • 所有引用类型(函数,数组,对象)都拥有proto属性(隐式原型)、constructor属性
  • 所有函数除了有proto属性之外还拥有prototype属性(显式原型)
  • 原型对象:每创建一个函数,该函数会自动带有一个prototype属性,该属性是一个指针,指向一个对象,为原型对象。
  • 实例对象a的隐式原型指向它构造函数的显式原型
    1. function A() {...}
    2. var a = new A();
    3. a._proto_ === A.prototype;

    原型链

    原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法
    在对象实例和它的构造器之间建立一个链接(它是proto属性,是从构造函数的prototype属性派生的),之后通过上溯原型链,在构造器中找到这些属性和方法

参考文档:一篇文章让你搞懂原型和原型链