JS原型及原型链的简单理解

267 阅读2分钟

这是我个人感觉最能将原型链关系展示的一目了然的图片了


首先我们来介绍一下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,加油,共勉