對於原型鏈的一點理解

2021-09-12 06:31:03 字數 3738 閱讀 5499

先舉個簡單的例子

var a = 0

a.data='data'//可以用a.data取值

a.__proto__.data1='data1'//可以用a.data1取值

a.__proto__.__proto__.data2='data2'//可以用a.data2取值

a.__proto__.__proto__.__proto__.data3='data3'//cannot set property 'data3' of null

這就是傳說中的原型鏈,訪問物件的屬性的時候如果物件的屬性中有這個字段,則直接返回,如果物件中沒有這個字段,則從物件的__proto__中尋找,如果__proto__中沒有,就從__proto__.__proto__中尋找。直到__proto__.......__proto__為null。

接下來一層一層剖析,

1.var a=0

列印出來a就是個0,

接下來列印a.__proto__

number 

知識點:乙個物件的__proto__就是這個物件的建構函式的prototype,所有物件都有__proto__和constructor屬性,所有函式都有prototype屬性,函式也是物件,所以函式有這三個屬性

也就是說a的建構函式是number,

再列印typeof number

"function"

也就是說,number其實是個函式,所以對a而言,number就是建構函式了,對,就是個函式,跟我們寫的function一樣,只是function fun(){} var f=new fun(); typeof f的結果是object

2.既然透過表象看到了本質,那就再來看看function

function fun(){}

var f = new fun();

typeof f

輸出"object"

f也就是new出來的乙個函式物件

接下來加幾個屬性

function fun()

fun.__proto__.b = 'bbbb'

fun.prototype.c = 'cccc'

var f = new fun()

f.d = 'dddd'

f.__proto__.e = 'eeee'

//f是物件,所以沒有prototype,所以不能f.prototype.x='***x'

//這裡不使用this.name='abc',因為function有name屬性,以免造成歧義

命令及其輸出:

f.e"eeee"

f.d"dddd"

f.c"cccc"

f.bundefined

f.a"aaaa"

f.e是f.__proto__的屬性,不是f的屬性,f的__proto__也就是f的建構函式的prototype,跟fun.prototype.c乙個級別的,證明:

fun.prototype

f.d是給f新增屬性,也就是f自己的內容,不用證明,但還是列印一下:

ffun 

c就不用說了,只能再次證明f.__proto__===fun.prototype

fun.__proto__.b是fun.__proto__的屬性不是f的原型鏈上的,因為原型鏈只是__proto__屬性的鍊錶,fun自己本身就是乙個函式,

fun instanceof object

true

他有自己的__proto__,沒有參與到f的原型鏈上。

小擴充套件:

var g = new fun()

g.a"aaaa"

f.__proto__===g.__proto__

true

這個例子更說明了乙個物件的多個實列的__proto__源自同乙個prototype

f是個物件的描述可能不夠準確,f應該是乙個物件的例項

3.function都看了,再來看看function

書接上例,主要講fun的例項的屬性,以及自己的__proto__和prototype,那麼

fun.__proto__.b呢

function.b

"bbbb"

知識點:函式的建構函式是funciton,function的建構函式是function自身

function.constructor===function

true

如果fun.g='gggggg',該怎麼獲取呢??

只能用fun.g獲取,因為fun的例項只是獲取了fun的prototype,而fun是乙個function實列,fun的建構函式要想獲取得用fun.__proto__也就是fun獨有的屬性,

f.a能獲取到a是因為this.a中this是實列物件,也就是new的時候的那個物件也就是f,而g不是this的,是fun的。

4.已經知道了__proto__的作用:獲取屬性值,充當原型鏈,物件的__proto__就是這個物件的建構函式的prototype

接下來看看prototype

函式自己可以有__proto__,他的例項可以繼承這個__proto__,他的實列的__proto__就是這個函式的prototype,也就是說prototype的作用就是用來給他的實列的__proto__賦值,沒錯就只做這個事情了。

雖然說起來很簡單,但是要理解prototype中存放了什麼,存放了這個原型的所有屬性,因為例項的__proto__的屬性都是從這個prototype中來的,所以prototype也算是乙個原型的所有例項的容器,所有例項只會繼承prototype的引用,這樣就達到了乙個屬性的修改,在所有例項中生效,看起來是__proto__的作用,但是每個例項的__proto__都來自同乙個prototype,才能實現這個效果

function fun()

var f1 = new fun()

var f2 = new fun()

f1.b='bbb'

f1.__proto__.c='ccc'

f1fun 

f2fun 

f2.c

"ccc"

f2能取到f1設定的c屬性,就是這個作用

fun.prototype

c: "ccc"

constructor: ƒ fun()

__proto__: object

不給protoype賦值的話,prototype只有乙個constructor函式,和所有物件都有的__proto__屬性。

5.constructor就是建構函式

f1.constructor===fun

true

f1.constructor.__proto__===object.__proto__

true

f1.constructor===object

false

f1.constructor.__proto__==function.__proto__

true

f1.constructor.__proto__==function

false

f1.constructor.__proto__==array.__proto__

true

function.constructor===function

true

就不贅述了,constructor就只是函式,function的建構函式是function本身

6.小擴充套件:

class c extends fun{}

c輸出:class c extends fun{}

class可以繼承自function

class就是個特殊的function

對於錘子科技的一點理解

最近總聽到有 爆料錘子要倒閉了,自己也是乙個數碼愛好者,隨便談談自己對錘子科技的一點認識吧。乙個外行人 拿著風投圓自己的夢。我覺得是對錘子最好的定位。全世界有多少手機廠商?比錘子有錢的,有經驗的至少有十家吧,怎麼就沒發現走情懷,工匠精神這條路能生存?肯定是這裡面有很多連這些大廠都不願去觸碰的問題。消...

對於POJ 1011的一點理解

description 喬治拿來一組等長的木棒,將它們隨機地砍斷,使得每一節木棍的長度都不超過50個長度單位。然後他又想把這些木棍恢復到為裁截前的狀態,但忘記了初始時有多少木棒以及木棒的初始長度。請你設計乙個程式,幫助喬治計算木棒的可能最小長度。每一節木棍的長度都用大於零的整數表示。input 輸入...

小白對於BERT細節的一點理解

最初在部落格看過對於bert的講解,閱讀原始 發現bert主要包括以下三點內容 1 使用transformer的進行雙向訓練。2 輸入向量包括token embedding segment embedding position embedding三部分 3 使用了mask language mode...