JS#3 原型与原型链
2018-12-03 本文已影响15人
Yixi_Li
来看一个例子:
var n = new Number(1)
var s = new String('s')
var b = new Boolean(true)
var o = new Object()
这几个对象在内存中是这样的:
![](https://img.haomeiwen.com/i4467450/dc7942de5f019513.png)
大家都知道js中的对象有一些共有的方法,如valueOf(),toString()
![](https://img.haomeiwen.com/i4467450/7c196b589ab4d76d.png)
想一个问题,我们只是声明了一个对象,没有添加这些方法,那么这些方法是从哪里来的呢?
如果让你给这些对象添加这些默认的方法,你会怎么做呢?
第一种方法就是给每个对象本身添加一个valueOf, toString等方法
如下:
![](https://img.haomeiwen.com/i4467450/d8c8bbd9c3a3d50d.png)
可是每个对象有这么多属性会很占内存,既然这些属性都一样,我们就可以把它们放在一个公共属性里.
![](https://img.haomeiwen.com/i4467450/031b85becb934703.png)
当你调用对象的valueOf方法时,我就去这个公共的对象中去拿这些方法。
那么JS是如何做的呢?
他用一个隐藏的属性proto,来存这个公有对象的地址, 如下图:
![](https://img.haomeiwen.com/i4467450/251809d5a43edeac.png)
来看这张图:
![](https://img.haomeiwen.com/i4467450/c602750299be7559.png)
toSting方法在哪里呢??? 把这个proto点开就有了:
![](https://img.haomeiwen.com/i4467450/b6f9926625d0cd1b.png)
这样,当你访问你一个对象的某个方法时,他会先检查自身有没有这个方法,没有的话就去proto中去找这个方法,如果自身有这个方法,则使用自身的方法。
JS就是通过proto来组织各个对象之间的关系
思考一个难一点的问题:上面声明的数字对象n中不只有toString,还有toFixed方法,还有自己专有的toString方法,而对象o是没有这个方法的,那么toFixed方法在哪里呢??
方法就是给数字类型的对象专门加一个公有的对象,使其proto指向这个对象。来看图:
![](https://img.haomeiwen.com/i4467450/784a12a63a7e1426.png)
这时候当你调用toFixed方法时,他会现在地址为97的对象中找这个方法,找到了直接使用。
所以先在地址为97的对象中找,找不到了再去地址为77的对象里找,而对象类型的proto则直接指向地址为77的内存
同理String,和Boolean;
我们通常把这些公有属性叫做原型,也就是Number.prototype, String.prototype, Object.prototype, 而你找某个对象的方法,不停的找,形成的这条链子就是原型链。他们之间就是通过该proto来连接的
可得:
var n1=new Number(1);
n1._proto_ ===Number.prototype;
n1._proto_._proto_===Object.prototype;