JS#3 原型与原型链

来看一个例子:

var n = new Number(1)
var s = new String('s')
var b = new Boolean(true)
var o = new Object()

这几个对象在内存中是这样的:


image.png

大家都知道js中的对象有一些共有的方法,如valueOf(),toString()

如下图:
image.png

想一个问题,我们只是声明了一个对象,没有添加这些方法,那么这些方法是从哪里来的呢?
如果让你给这些对象添加这些默认的方法,你会怎么做呢?
第一种方法就是给每个对象本身添加一个valueOf, toString等方法

如下:


image.png

可是每个对象有这么多属性会很占内存,既然这些属性都一样,我们就可以把它们放在一个公共属性里.


image.png

当你调用对象的valueOf方法时,我就去这个公共的对象中去拿这些方法。

那么JS是如何做的呢?

他用一个隐藏的属性proto,来存这个公有对象的地址, 如下图:

image.png

来看这张图:
image.png

toSting方法在哪里呢??? 把这个proto点开就有了:
image.png

这样,当你访问你一个对象的某个方法时,他会先检查自身有没有这个方法,没有的话就去proto中去找这个方法,如果自身有这个方法,则使用自身的方法。
JS就是通过proto来组织各个对象之间的关系

思考一个难一点的问题:上面声明的数字对象n中不只有toString,还有toFixed方法,还有自己专有的toString方法,而对象o是没有这个方法的,那么toFixed方法在哪里呢??

方法就是给数字类型的对象专门加一个公有的对象,使其proto指向这个对象。来看图:

image.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;

你可能感兴趣的:(JS#3 原型与原型链)