1.JS 里的數(shù)據(jù)
1.1.轉(zhuǎn)化為字符串(console.log就是這個(gè)原理)
1.1.1.tostring





null和undefined沒(méi)有tostring這個(gè)API。所以也無(wú)法轉(zhuǎn)化類型。API就是對(duì)象?鍵值對(duì)的集合?
函數(shù)也行,函數(shù)當(dāng)作一個(gè)對(duì)象寫在里面也行。

Number、string、Boolean自己就是API,自己里面又有tostring這個(gè)對(duì)象或者說(shuō)這個(gè)API
1.1.2.但是tostring很難寫,老司機(jī)不是這么寫的
通過(guò)類型+ '',就可以轉(zhuǎn)化為字符串


本來(lái)不同類型是不能相加的,但是你偏這么寫了瀏覽器就幫你把數(shù)字先轉(zhuǎn)化為字符串,然后再把字符串拼接起來(lái)。
1.1.3.window.String

1.2.轉(zhuǎn)化為布爾
Boolean

!!任何東西取反兩次就是布爾

js轉(zhuǎn)化布爾的時(shí)候只有5個(gè)false。這些要記下來(lái)。false自己就不算了,它自己當(dāng)然是false了


mdn falsy

1.3.轉(zhuǎn)為number

parseInt的時(shí)候后面的10就是10進(jìn)制的意思。parseFloat不用加幾進(jìn)制,因?yàn)楦↑c(diǎn)數(shù)都是10進(jìn)制表示的。
第四種是字符減一個(gè)0,第五種是字符前面用一個(gè)+,但是用的最多的還是第4中因?yàn)楹美斫?,?種可能會(huì)理解錯(cuò)。

考試重點(diǎn)考第二種。


這個(gè)parseInt的意思是把字符解析成int,所以能解析多少就解析多少。所以parseInt('1s')只會(huì)解析1
1.4.轉(zhuǎn)null和undefined沒(méi)有意義
1.5.轉(zhuǎn)化成對(duì)象
2.內(nèi)存圖

瀏覽器妖給HTML+CSS渲染引擎,JS引擎,HTTP引擎還有其他東西。

代碼區(qū)和數(shù)據(jù)區(qū),數(shù)據(jù)區(qū)又分stack棧內(nèi)存和heap堆內(nèi)存

1.瀏覽器首先在代碼區(qū)左變量提升,把變量都拿到最上面去。把a(bǔ),b,o,c都放到第一行去
2.然后在stack里面用64位里面,寫了一個(gè)1這個(gè)內(nèi)存是對(duì)應(yīng)a的怎么對(duì)應(yīng)引擎自己會(huì)搞定。
3.然后同理把b給存了。
4.然后發(fā)現(xiàn)o那就繼續(xù)存,一個(gè)字符會(huì)用掉2字節(jié),16位。所以一行可以放4個(gè)字符。所以o就專業(yè)楊存掉了。
5.然后存c
6.然后給o加屬性,這時(shí)候就尷尬了,c已經(jīng)在前面了。所以只能把c往下移??粘龊蟀l(fā)現(xiàn)不夠再移。那如果已經(jīng)有100個(gè)c怎么辦,都往下移嗎。所以非常慢。

上面提出的問(wèn)題的解決方案是:o在stack內(nèi)存里就不放o的內(nèi)容我放一個(gè)地址,實(shí)際內(nèi)容放到heap內(nèi)存里面。每次聲明了對(duì)象以后就會(huì)隨機(jī)給stack一個(gè)heap的地址。heap想加就加不會(huì)限制大小,heap好像很大。
另外如果兩個(gè)對(duì)象賦值。比如var o2= o1不是heap里面復(fù)制o1再覆蓋o2。而是直接把o1的地址復(fù)制一下給o2。讓o2直接指向o1就行了。那o2原來(lái)的內(nèi)容應(yīng)該會(huì)被回收。
引用:對(duì)象的變量名是鍵值對(duì)的引用。stack是heap的引用

變量之間的賦值,都是賦值stack里面的內(nèi)容。變量和對(duì)象之間的賦值是把對(duì)象的地址給變量。比如b = { 'name' : 'b'}意思是先創(chuàng)建出{'name' : 'b'}在heap里面。然后把這些東西的地址給b。所以a.name = a .
所以stack里面的賦值和heap給stack賦值是不一樣的。

為什么是self是undefined呢,因?yàn)殚_始變量上提以后,a就被掛到stack上面了。然后生成{self: a}這時(shí)候還沒(méi)把{self: a}的地址給a,所以a是沒(méi)有定義的。
對(duì)象的聲明分三部分:
1.變量上提,放到stack
2.heap上面創(chuàng)建對(duì)象,同時(shí)擁有該對(duì)象的地址
3.把地址給變量

如果先聲明a = { }就會(huì)有地址了,空的對(duì)象也行,反正有容器了就會(huì)給一個(gè)地址了。


可以把a(bǔ).x = a = { n: 2}拆成a.x = a; a= {n: 2}
然后每次畫圖的時(shí)候stack這邊就把heap的對(duì)象的地址寫上去。然后對(duì)象里面=變量的話,把變量的內(nèi)容即地址寫上去?;静粫?huì)錯(cuò)了。

heap沒(méi)有被stack引用將被回收。什么 時(shí)候回收。瀏覽器自己判斷它覺(jué)得內(nèi)存不太夠了就會(huì)來(lái)回收。賦值時(shí)右邊給左邊。a = b是b賦值給a


所以fn不是垃圾,document.body.onclick = fn這個(gè)圖要畫出來(lái)。
只有document是在stack里面,document里面的屬性就算是對(duì)象,他的變量名也是存放heap里面的地址,它自己也在heap里面。


這樣寫的話fn就被回收了。畫圖的時(shí)候時(shí)刻想著對(duì)象名放的是對(duì)象值的地址。
深拷貝、淺拷貝
引用

