來看一個例子:
var n = new Number(1)
var s = new String('s')
var b = new Boolean(true)
var o = new Object()
這幾個對象在內(nèi)存中是這樣的:

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

image.png
想一個問題,我們只是聲明了一個對象,沒有添加這些方法,那么這些方法是從哪里來的呢?
如果讓你給這些對象添加這些默認的方法,你會怎么做呢?
第一種方法就是給每個對象本身添加一個valueOf, toString等方法
如下:

image.png
可是每個對象有這么多屬性會很占內(nèi)存,既然這些屬性都一樣,我們就可以把它們放在一個公共屬性里.

image.png
當(dāng)你調(diào)用對象的valueOf方法時,我就去這個公共的對象中去拿這些方法。
那么JS是如何做的呢?
他用一個隱藏的屬性proto,來存這個公有對象的地址, 如下圖:

image.png
來看這張圖:

image.png
toSting方法在哪里呢??? 把這個proto點開就有了:

image.png
這樣,當(dāng)你訪問你一個對象的某個方法時,他會先檢查自身有沒有這個方法,沒有的話就去proto中去找這個方法,如果自身有這個方法,則使用自身的方法。
JS就是通過proto來組織各個對象之間的關(guān)系
思考一個難一點的問題:上面聲明的數(shù)字對象n中不只有toString,還有toFixed方法,還有自己專有的toString方法,而對象o是沒有這個方法的,那么toFixed方法在哪里呢??
方法就是給數(shù)字類型的對象專門加一個公有的對象,使其proto指向這個對象。來看圖:

image.png
這時候當(dāng)你調(diào)用toFixed方法時,他會現(xiàn)在地址為97的對象中找這個方法,找到了直接使用。
所以先在地址為97的對象中找,找不到了再去地址為77的對象里找,而對象類型的proto則直接指向地址為77的內(nèi)存
同理String,和Boolean;
我們通常把這些公有屬性叫做原型,也就是Number.prototype, String.prototype, Object.prototype, 而你找某個對象的方法,不停的找,形成的這條鏈子就是原型鏈。他們之間就是通過該proto來連接的
可得:
var n1=new Number(1);
n1._proto_ ===Number.prototype;
n1._proto_._proto_===Object.prototype;