来看一个例子:
var n = new Number(1)
var s = new String('s')
var b = new Boolean(true)
var o = new Object()
这几个对象在内存中是这个样子:
大家都知道js中的对象有一些共有的方法,如valueOf(),toString()
如下图:
想一个问题,咱们只是声明了一个对象,没有添加这些方法,那么这些方法是从哪里来的呢?
如果让你给这些对象添加这些默认的方法,你会怎么做呢?
第一种方法就是给每个对象本身添加一个valueOf, toString等方法
如下图示:
你有没有觉得这种方法很SB?每个对象有这么多属性不是很占内存吗?
每个对象的这些方法都一模一样,你为什么不把这些方法放在一个公有的属性中呢?
于是就有了这张图:
当你调用对象的valueOf方法时,我就去这个公共的对象中去拿这些方法。
那么JS是如何做的呢?
他用一个隐藏的属性__proto__,来存这个公有对象的地址, 如下图:
来看这张图:
toSting方法在哪里呢??? 把这个__proto__点开就有了:
这样,当你访问你一个对象的某个方法时,他会先检查自身有没有这个方法,没有的话就去__proto__中去找这个方法,如果自身有这个方法,则使用自身的方法。
JS就是通过__proto__来组织各个对象之间的关系
思考一个难一点的问题:上面声明的数字对象n中不只有toString,还有toFixed方法,还有自己专有的toString方法,而对象o是没有这个方法的,那么toFixed方法在哪里呢??
方法就是给数字类型的对象专门加一个公有的对象,使其__proto__指向这个对象。来看图:
这时候当你调用toFixed方法时,他会现在地址为90的对象中找这个方法,找到了直接使用。
类似的,String对象也一样:
我们通常吧这些公有属性叫做原型,也就是Number.prototype, String.prototype, Object.prototype, 而你找某个对象的方法,不停的找,形成的这条链子就是原型链。他们之间就是通过该__proto__来连接的
来看代码:
完。