來(lái)看一個(gè)例子:
var n = new Number(1)
var s = new String('s')
var b = new Boolean(true)
var o = new Object()
這幾個(gè)對(duì)象在內(nèi)存中是這樣的:
image.png
大家都知道js中的對(duì)象有一些共有的方法洪乍,如valueOf()靶溜,toString()
image.png
想一個(gè)問題开瞭,我們只是聲明了一個(gè)對(duì)象,沒有添加這些方法罩息,那么這些方法是從哪里來(lái)的呢嗤详?
如果讓你給這些對(duì)象添加這些默認(rèn)的方法,你會(huì)怎么做呢瓷炮?
第一種方法就是給每個(gè)對(duì)象本身添加一個(gè)valueOf葱色, toString等方法
如下:
image.png
可是每個(gè)對(duì)象有這么多屬性會(huì)很占內(nèi)存,既然這些屬性都一樣,我們就可以把它們放在一個(gè)公共屬性里.
image.png
當(dāng)你調(diào)用對(duì)象的valueOf方法時(shí),我就去這個(gè)公共的對(duì)象中去拿這些方法娘香。
那么JS是如何做的呢苍狰?
他用一個(gè)隱藏的屬性proto,來(lái)存這個(gè)公有對(duì)象的地址烘绽, 如下圖:
image.png
來(lái)看這張圖:
image.png
toSting方法在哪里呢淋昭??诀姚? 把這個(gè)proto點(diǎn)開就有了:
image.png
這樣响牛,當(dāng)你訪問你一個(gè)對(duì)象的某個(gè)方法時(shí),他會(huì)先檢查自身有沒有這個(gè)方法赫段,沒有的話就去proto中去找這個(gè)方法呀打,如果自身有這個(gè)方法,則使用自身的方法糯笙。
JS就是通過(guò)proto來(lái)組織各個(gè)對(duì)象之間的關(guān)系
思考一個(gè)難一點(diǎn)的問題:上面聲明的數(shù)字對(duì)象n中不只有toString贬丛,還有toFixed方法,還有自己專有的toString方法给涕,而對(duì)象o是沒有這個(gè)方法的豺憔,那么toFixed方法在哪里呢额获??
方法就是給數(shù)字類型的對(duì)象專門加一個(gè)公有的對(duì)象恭应,使其proto指向這個(gè)對(duì)象抄邀。來(lái)看圖:
image.png
這時(shí)候當(dāng)你調(diào)用toFixed方法時(shí),他會(huì)現(xiàn)在地址為97的對(duì)象中找這個(gè)方法昼榛,找到了直接使用境肾。
所以先在地址為97的對(duì)象中找,找不到了再去地址為77的對(duì)象里找,而對(duì)象類型的proto則直接指向地址為77的內(nèi)存
同理String,和Boolean;
我們通常把這些公有屬性叫做原型,也就是Number.prototype, String.prototype, Object.prototype胆屿, 而你找某個(gè)對(duì)象的方法奥喻,不停的找,形成的這條鏈子就是原型鏈非迹。他們之間就是通過(guò)該proto來(lái)連接的
可得:
var n1=new Number(1);
n1._proto_ ===Number.prototype;
n1._proto_._proto_===Object.prototype;