原型 、原型链和对象是怎么实现继承的

什么是原型?

  声明函数时 js会自动在你声明的函数对象(js一切皆对象)上挂载一些方法和属性  其中prototype属性就是   原型(也称为原型对象) 如下图:

这个原型对象里面保存着 constructor 自己的函数体(也就是Pro.prototype.constructor)  看下图就应该知道了吧 (Pro === Pro.prototype.constructor):

  这个原型对象里面还保存着 __proto__ 这个__proto__指向的就是Object.prototype(Pro.prototype.__proto__ === Object.prototype 它们两个是一个“东西”)    里面保存着 所有,js自带对象 Object下的方法如下图:

 在对象使用方法(或属性)时会查找自身原型(prototype)上的constructor有没有我使用的这个方法(或属性),如果没有就去自身原型(prototype)的就像指向父级原型的__proto__查找

这里我说一下   prototype是自身原型       __proto__是父级原型(指向父级原型 也就是父级原型)

找到父级原型 上图看到 父级原型上的constructor 下有很多方法。。。

我画绿线的地方 是我其他篇文章《对象属性类型》和《作用域和作用域链》介绍过的方法和属性。。有兴趣的可以去看一看

画绿圈的地方是我接下来要说的  构造函数下有__proto__和prototype(最上面的图显示出了这两个属性) 我前面还提到了 constructor就是自身函数体

   用上图的Pro函数来举例子‘:

    Pro函数   可称成为构造函数   也可称为函数体  

    Pro.prototype.constructor存储的是自身函数体 

    自身函数体.prototype === Pro.prototype

    自身函数体就是Pro函数

    所以这地方是一个无线循环

    Pro.prototype.constructor === 自身函数体 (上面说了 自身函数体就是Pro函数 所以)Pro.prototype.constructor.prototype  = = = Pro.prototype

  有点乱 但是我相信多想想能理解。。。

上图还圈了一个属性 __proto__  构造函数下有__proto__和prototype  这里我在解释一边  我上图圈的那个__proto__就是 构造函数Pro(函数体),

Function和Object一样都是js自带函数对象

所以说是Pro.__proto__.上面只说了原型上的__proto__下面说说  构造函数的__proto__ 指向 所有构造函数的__proto__都指向Function.prototype,

  记住所有构造函数 包括他自己    Function函数

  

  直接输出是看不到里面的东西的   但是也说明 有Function对象  然后我就想那new 出来一个实例  然后在     实例.__proto__    但是我发现new出来的实例居然有 prototype   (这里说明一下 除了Function的实例,其他对象的实例是没有prototype的)

  

  这里 new Function 怎么会有prototype那    因为

new Function 也是创建函数的一种方式   (js规定的)        这时候就可以解释为什么   Function.__proto__ === Function.prototype

 那么我们从Function上面得到什么了 毕竟所有构造函数的__proto__都指向 Function.prototype了

由于Function.prototype是无法直接访问的  所以我们使用Object.getOwnPropertyNames方法获取  Funciton.prototype上都有什么

上面也看到了。。。 Funciton.prototype有这些方法   证实一下  也证实上面说的,所有构造函数的__proto__都是Function.prototype

发现多一个 Symbol   这个是es6新增基础类型  需要使用Object.getOwnPropertySymbols获取

这个提一下  原型链顶端就是 Object.prototype.__proto__ = null   谷歌上控制台输出的不明确   这里用IE 输出一下   

上图也是输出 Object.prototype.constructor.__proto__

所有构造函数的__proto__都是Function.prototype

 那我为什么不知 直接 Object.__proto__

这就还是是想证明一下 Object.__proto__===Object.prototype.constructor.__proto__

上图发现了  在谷歌上输出 原型和IE上显示输出的方法不一样   比如  get  __proto__ 、set  __proto__    和IE 的 __proto__ 

 

应该是谷歌浏览器 对js内置对象的一种修改  具体是怎么修改的和修改什么了  我也不清楚了。。。如果有知道的  请在下方留言谢谢!!!!

说的零零散散   最后需要总结一下。。。

原型就是 prototype   原型链 就是我在的原型上找不到的东西 我回去我的父级找 __proto__ 就是父级的指针     如下图:

我创建了一个构造函数  Pro     

我又把Pro实例化  并且 赋值给了p   

p.toString()  实例对象p下是没有toString的

p.__proto__  ===Pro.prototype 下constructor里面没有 toString方法

然后就找Pro.prototype.__proto__  ===Object.prototype

Object.prototype.constructor下找到了toString方法   

所以才执行并且输出了    有兴趣可以百度查查  Object下的toString()方法怎么实现的。。。。

我为什么能使用toString()那  是因为我从 Object对象上继承而来的   所以这里说一下 js 是根据原型链来实现继承的啦    在有不懂了  可以看下面这个图   这个图要记下来  

  这个图我也忘了 是从哪篇文章找到得了   我是因为看了那篇文章 才明白的原型链   。。。在这里我感谢一下那篇文章的作者   还有图借我用一下  哈哈。。。

 

posted @ 2019-05-30 13:05  树下的老大爷  阅读(972)  评论(0编辑  收藏  举报