亲宝软件园·资讯

展开

js 原型与原型链

族语1996 人气:0
### 前言 什么是原型? ``` 原型,汉语词语,读音为yuán xíng。指原来的类型或模型,特指文学艺术作品中塑造人物形象所依据的现实生活中的人。 ``` 狭义上将是原型人物。通常这样的解释,往往我们会觉得原型与产品之间,是在原型上破坏性的加工。 如果这样理解的话,那么将会对js的原型理解艰难,因为英文翻译过来是抽象的。 js的原型是扩展的意思,就像我们学数据结构的双向链表一样。 ![](https://img2020.cnblogs.com/blog/1289794/202003/1289794-20200313100121098-1013013697.png) 也就是说原型是扩展的对象的一个属性。 那么什么是原型链? ![](https://img2020.cnblogs.com/blog/1289794/202003/1289794-20200313100633304-1304378593.png) 原型链指的是指向原型的这条连接,直到指向null为指,因为这个时候链接就断了。 好的概念理解完了,开始正文吧。下面理解,均为个人理解,如有不对望指出。 ### 正文 上面写道扩展对象的一个属性指向了原型,那么这个属性是什么? 是__proto__。 #### __proto__ 与 prototype 看一段代码: ``` var obj= new Object(); consoleProto(obj); function consoleProto(obj){ if(obj!=null) { console.log(obj.__proto__); consoleProto(obj.__proto__); } } ``` ![](https://img2020.cnblogs.com/blog/1289794/202003/1289794-20200313104108795-1899893756.png) 上文我通过递归的方式,把原型链打印了出来。 也就是说我创建一个对象,都会有一个属性__proto__指向另外一个对象。 ![](https://img2020.cnblogs.com/blog/1289794/202003/1289794-20200313104446620-550736328.png) 现在我不关心null,我更关心的是红框中的对象到底是啥? 接来下我写了另一段代码: ``` var obj= new Object(); var obj2=new Object(); console.log(obj.__proto__===obj2.__proto__); ``` 返回的结果为:true。 这个说明什么呢?说明任何一个对象的原型最终会基于一个公共原型对象。 也就是说new Object() 会把一个新的对象增加一个公共的对象引用。 那么new Object()是如何获取这个对象的呢?调用了什么函数可以获取到这个对象?或者说Object本身就带有这个公共属性? 我写下了另外一段代码: ``` ``` 结果为true。 原来Obect本身就带有这个属性。 ![](https://img2020.cnblogs.com/blog/1289794/202003/1289794-20200313115142218-314255995.png) 那么再往上推,Object是什么,Object是一个函数。 把Object 打印出来,然后提出疑问是否每个函数都具有prototype 属性? ``` function Object1(){ } console.log(prototype); console.log(Object1.prototype==Object.prototype); ``` 打印出来是prototype 有值,后面的结果为false。 证明了每个函数,都具有prototype,但是Object比较特殊,其Object内置函数。 他们的关系如下: ``` console.log(Object1.prototype.__proto__==Object.prototype); ``` 那么现在单独讨论Object1,Object1是一个函数但是同时也是一个对象,那么从对象的角度来看下,对象想到的是__proto__. ``` function Object1(){ } console.log(Object1.__proto__==Function.prototype); ``` 得出的结果为true。 如图: ![](https://img2020.cnblogs.com/blog/1289794/202003/1289794-20200313123019182-159474159.png) 那么上图中的原型对象是否就是原始对象。有两种方法可以证明一种就是没有原型,一种就是和原始对象做对比。 ``` console.log(Object1.__proto__==Object.prototype); ``` 我采用第二种,结果不是。同时说明Fuction 不是 Object的构造函数。 实际上是这样的: ``` console.log(Function.prototype==Function.prototype); console.log(Function.prototype.__proto__==Object.prototype); ``` ![](https://img2020.cnblogs.com/blog/1289794/202003/1289794-20200313134310378-1955278712.png) 两者都为true。 上述结论图: ![](https://img2020.cnblogs.com/blog/1289794/202003/1289794-20200313140314537-1433543565.png) 其中内置方法没有prototype,所以不是每个函数都有prototype。 #### 再次__proto__ 与 prototype 上述提及的是内部的对象关系,那么我们书写的时候不用理会这么多了。 ``` function Tree(){ } var newtree=new Tree(); console.log(newtree.__proto__==Tree.prototype); ``` 关系为: ![](https://img2020.cnblogs.com/blog/1289794/202003/1289794-20200313141159905-2016486767.png) #### constructor 既然构造函数能够知道原型,原型是否能够知道构造函数,也是可以的。 ``` console.log(Tree==Tree.prototype.constructor); ``` 两者相生相伴,一起出生。 ![](https://img2020.cnblogs.com/blog/1289794/202003/1289794-20200313141820610-969157449.png) #### 为什么说原型链可以实现继承? ``` function Tree(){ } Tree.prototype.name="白杨树"; var newtree=new Tree(); console.log(newtree.name); ``` 这时候打印出来的是“白杨树“。也就是说如果newtree找不到,则会去根据原型链找原型,一直找下去,知道找到为止。 同样: ``` console.log(newtree.contructor==Person); ``` 也就是因为newtree没有这个属性,只好找原型了。 #### 最后一笔 ``` console.log(Tree.prototype.__proto__.constructor); ``` ![](https://img2020.cnblogs.com/blog/1289794/202003/1289794-20200313165337582-967333128.png) 修改一下: ![](https://img2020.cnblogs.com/blog/1289794/202003/1289794-20200313165520000-1198270181.png) ### 总结 以上皆为个人理解,如有不对,望请指点。

加载全部内容

相关教程
猜你喜欢
用户评论