在理解原型和原型链之前首先得明确它俩是什么货色:

原型:prototype
又称显示原型
1、原型是一个一般对象
2、只有构造函数才具备该属性
3、私有属性可操作

隐式原型:__proto__
1、只有对象(一般对象、函数对象)具备
2、公有的对象属性,不可操作

有了下面的概念之后,咱们再来探讨一下什么是原型和原型链。

原型(显示原型) : prototype

咱们定义一个字符串变量的时候,该字符串自身是不具备任何办法的,然而能够调用字符串办法。

let str = 'hello'  // new String()console.log(str);console.log(str.length);

其实咱们在定义一个字符串变量的时候,隐式的实例化了new String()这个构造函数,所以咱们才能够应用字符串办法。

 console.log(new String());

这个length就是String的原型办法ptototype,字符串自身有没有这个办法不重要,字符串的原型上有个办法就能够了。
原型的实质是一个一般对象,所以咱们能够利用对象.属性的形式调用办法。
如果咱们用字符串调用一个DCodes(),该办法在字符串属性上没有并不存在,调用该办法会报错。

咱们给String的原型增加一个DCodes办法,字符串就能够调用该办法了。

String.prototype.DCodes = function(){       console.log('你好DCodes');}str.DCodes() // 你好DCodes

利用原型能够干什么呢?下面也说了,构造函数才具备原型,咱们创立一个构造函数,能够通过实例化这个构造函数来调用原型办法和原型属性。

// 构造函数function Person(){         this.name = '东方不败'}let per = new Person()console.log(per);


原型的实质是一个对象,那么给Person这个原型增加一个办法

function Person(){         this.name = '东方不败'}Person.prototype.sum = function(a,b){return a + b}let per = new Person()console.log(per);console.log(per.sum(1,2));


构造函数记录了以后原型对象产生的归属,原型是基于那个构造函数构建的,那么constructor指向的就是那个构造函数,这里的constructor指向的就是Person()函数。


__proto__隐式原型

隐式原型只有对象(一般对象、函数对象)才具备,并且隐式原型是一个公有的对象属性,不可操作。
下面也提到过,咱们定义了一个字符串,实际上是隐式的new String()String()的原型上有length,所以字符串能够调用length办法,显示原型prototype是构造函数才具备的,一般对象是没有的,那么一般对象是怎么调用构造函数的原型办法的呢?答案就是一般对象具备隐式原型,隐式原型全等于显示原型

let hello = 'hello'console.log(hello.__proto__ === String.prototype);  // true


也就是说,一般对象的隐式原型__proto__等于构造函数的显示原型prototype,一般对象就能够调用构造函数的原型办法。
谷歌浏览器中,隐式原型__proto__的写法为: [[Prototype]]

到这里就形成了原型链,用字符串调用字符串办法的时候,字符串会在__proto__寻找对应的字符串办法,__proto__等于prototype,也就是String()构造函数,如果String()的构造函数没有该办法,那么String()会持续向上寻找,原型prototype是一个对象,那么对象就会有隐式原型__proto__String()的隐式原型__proto__Object(),而后会在Object()的原型prototype上寻找,如果Object()的原型prototype上不存在该属性,那么就会通过隐式原型__proto__持续向上寻找,直到找到对应的办法为止,如果没有找到,那么就会报错,该办法不存在。(这一段须要好好了解)
这样向上寻找,最终总会有止境,万物的原型起点是谁呢?
字符串、数组、构造函数的原型最终都会指向Object,而Object的原型指向的是null

console.log(Object.prototype);

最初咱们来看一下prototype、__proto__之间的关系:

__proto__ === prototype prototype == {}{}.__proto__ == Object.prototype......