
这是我个人感觉最能将原型链关系展示的一目了然的图片了
首先我们来介绍一下prototype、__proto__和constructor之间的关系
prototype与constructor之间的关系
- 当你新建一个函数时,会有一组特定的规则为你的函数创建一个prototype属性也就是图中的 XXX.prototype
与此同时,你的原型对象会被赋予一个constructor属性,该属性指向prototype属性所在的函数 这样我们就搞清了图中所有 function XXX()与 XXX.prototype之间的关系 附上代码
function Person(){}
console.log(Person.prototype.constructor === Person); //true
prototype与__proto__之间的关系
- 当构造函数进行实例化时,实例内部会自动获得一个指针,指向构造函数的原型对象 --- [[Prototype]]
虽然没有标准方式访问[[Prototype]],但各大浏览器(Firefox.chrome...)都支持一个属性 --- __proto__
简单来说其之间的关系为:函数的显示原型(prototype) 等于 实例的隐式原型(__proto__)

function Person(){}
let Sam = new Person();
console.log(Sam.__proto__ === Person.prototype) //true
注:虽然__proto__比较常见,但问题也很大,简单来说就是WEB标准中已经删除了__proto__,但浏览器仍然支持
详细见MDN --- Object.prototype.__proto__
- ES5中为我们定义了一个'getPrototypeOf'方法,用以替代__proto__
function Person(){}
let Sam = new Person();
console.log(Object.getPrototypeOf(Sam) === Person.prototype) //true

比较绕的点
- function Function() 的__proto__指针指向 function.prototype
那是因为Function本身是一个构造函数,每创建一个function对象相当于调用了一次new Function()方法,function Object也是同样的道理
这么看来貌似Function是最大的
但是!!!!俗话说的好,万物皆对象,这句话在JS中尤为重要
- 因为JS中的function本身继承于Object,
所以我们能看到Function.prototype和Person.prototype的__proto__指针都指向Object.prototype
真是应了那句:我管你叫哥,你管我叫爸(狗头保命)
附上代码
function Person(){}
console.log(Person.prototype.__proto__ === Object.prototype) //true
总结:
数据查找的顺序大致为
函数实例本身 --- 实例的原型对象(构造函数的原型对象) --- Object的原型对象 --- null
借鉴:《JavaScript高级程序设计(第三版)》+自己的理解
如有错误,希望提出
希望大家都能早日拿到心仪的offer,加油,共勉