什么是原型?es6
声明函数时 js会自动在你声明的函数对象(js一切皆对象)上挂载一些方法和属性 其中prototype属性就是 原型(也称为原型对象) 以下图:浏览器
这个原型对象里面保存着 constructor 本身的函数体(也就是Pro.prototype.constructor) 看下图就应该知道了吧 (Pro === Pro.prototype.constructor):函数
这个原型对象里面还保存着 __proto__ 这个__proto__指向的就是Object.prototype(Pro.prototype.__proto__ === Object.prototype 它们两个是一个“东西”) 里面保存着 全部,js自带对象 Object下的方法以下图:spa
在对象使用方法(或属性)时会查找自身原型(prototype)上的constructor有没有我使用的这个方法(或属性),若是没有就去自身原型(prototype)的就像指向父级原型的__proto__查找prototype
这里我说一下 prototype是自身原型 __proto__是父级原型(指向父级原型 也就是父级原型)指针
找到父级原型 上图看到 父级原型上的constructor 下有不少方法。。。对象
我画绿线的地方 是我其余篇文章《对象属性类型》和《做用域和做用域链》介绍过的方法和属性。。有兴趣的能够去看一看blog
画绿圈的地方是我接下来要说的 构造函数下有__proto__和prototype(最上面的图显示出了这两个属性) 我前面还提到了 constructor就是自身函数体继承
用上图的Pro函数来举例子‘:ci
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 是根据原型链来实现继承的啦 在有不懂了 能够看下面这个图 这个图要记下来
这个图我也忘了 是从哪篇文章找到得了 我是由于看了那篇文章 才明白的原型链 。。。在这里我感谢一下那篇文章的做者 还有图借我用一下 哈哈。。。