先舉個簡單的例子
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...