-
類型轉(zhuǎn)換
-
轉(zhuǎn)換為string戒傻、boolean
類型轉(zhuǎn)換中的一些特殊情況:
- 其他類型轉(zhuǎn)換為boolean時為false的有:
number :0,NaN恭理;
!!0
false
!!NaN
false
string :""(空字符串);
!!''
false
!!' ' //空格字符串為true
true
null、undefined:均為false荠医;
!!null
false
!!undefined
false
值為 false 總結(jié):
if (false)
if (null)
if (undefined)
if (0)
if (NaN)
if ('')
if ("")
if (document.all) [1]
- object全部為true
-
轉(zhuǎn)換為number
一般情況下,只會將0-9組成的字符串轉(zhuǎn)換成 number,轉(zhuǎn)換方法有:
Number('1')===1;
-
parseInt('011',10)===11;
;parseInt('011',8)===9;
;parseInt('011',2)===3;
parseFloat('1.23')===1.23;
'1'-0===1;
-
+'1'===1;
;+'-1'===-1;
以上5中方法是將只有0-9組成的字符串轉(zhuǎn)換成 number的方法彬向,然而對于包含非數(shù)字的字符串豫喧,parseInt()、parseFloat() 方法依然有效幢泼;
比如:
Number('111a')
NaN
-------------
parseInt('011sd')
11
parseInt('011sd11',2)
3
-----------
parseFloat('011.4sd.23')
11.4
---------
'122ff'-0
NaN
-----------------
+'01a'
NaN
注意:parseInt()紧显、parseFloat()會從左往右開始轉(zhuǎn)換遇到的數(shù)字,直到非數(shù)字就結(jié)束缕棵。
-
內(nèi)存圖
此處孵班,只通過以下幾張圖簡單了解JS的在所分配的內(nèi)存中的一些存儲過程。
-
內(nèi)存分配簡圖
js-21-01.png
內(nèi)存是讀寫速度最快的招驴,當(dāng)前運行的程序都會拷貝到內(nèi)存中運行篙程。開機就是將操作系統(tǒng)讀取到內(nèi)存中運行。
- 假定瀏覽器給JS分配了100M內(nèi)存别厘,那JS是如何使用的虱饿??
js-21-02.png
JS會將分到的內(nèi)存劃分為代碼區(qū)和數(shù)據(jù)區(qū)触趴,比如代碼var a=1;
氮发,a 就存在代碼區(qū),數(shù)字1則存在數(shù)據(jù)區(qū)冗懦,兩者之間會有某種關(guān)聯(lián)爽冕。 -
數(shù)據(jù)區(qū)又是如何存儲的?披蕉?
js-21-03.png
數(shù)據(jù)區(qū)會劃分為2塊颈畸,棧內(nèi)存和堆內(nèi)存;
當(dāng)瀏覽器開始運行代碼區(qū)的代碼時没讲,第一步首先是:變量提升眯娱;之后才開始運行,運行時也就開始將數(shù)據(jù)存儲在數(shù)據(jù)區(qū)爬凑;
如上圖徙缴,數(shù)字1、2贰谣、.......在JS中都是以固定的64位2進制來存儲的娜搂,然而其他內(nèi)型并不都是按固定長度二進制來存儲的,那么如圖:如果隨著運行按順序存儲每一步的數(shù)據(jù)吱抚,當(dāng)給 對象 o 增加新的鍵值對時百宇,就需要在第一次存 o 的位置插入一段空間,這就很尷尬了...............
因此實際存儲時秘豹,根據(jù)數(shù)據(jù)類型荀澤對應(yīng)的存儲區(qū):
如上圖携御,實際對對象 o 的存儲是分2部分的,棧內(nèi)存中存的是一個地址,這個地址指向堆內(nèi)存中存放具體數(shù)據(jù)的一段空間啄刹。
當(dāng)執(zhí)行o2 = o;
涮坐,時:
會將棧內(nèi)存中 o 的數(shù)據(jù)(即地址)拷給 o2 ,之后 o 和 o2 實際指向堆內(nèi)存中同一空間誓军。
-
JS中7種數(shù)據(jù)類型的存儲方式
image.png
對于6種簡單類型昵时,直接存在stack中捷雕,關(guān)于string此處暫不討論;
對于Object類型壹甥,存在stack中的是對應(yīng)的heap中的一個空間的地址救巷,也就是Object的實際內(nèi)容是存儲在heap中,因此Object是對heap中一段空間的引用句柠。 幾個案例
-
如下圖:
image.png
-
如下圖:
image.png
首先浦译,回顧這一句:“=”只是把右邊的對應(yīng)的東西放到左邊的對應(yīng)的空間里。左邊是b溯职,那么b對應(yīng)的空間是精盅??缸榄?
b對應(yīng)的空間是: stack 給b分配的一小段空間渤弛;而右邊的是一個匿名 對象 ,首先給匿名對象在 heap 分配一個空間存放內(nèi)容甚带;之后再執(zhí)行“=”。 -
如下圖:
image.png
b.name對應(yīng)的空間是: b在stack里存的地址所指向的heap中的一個空間里的名為“name”的key所對應(yīng)的空間佳头;而右邊的是一個字符串 鹰贵,字符串是簡單類型;直接執(zhí)行“=”康嘉。
-
如下圖:
image.png
-
關(guān)于對象里的self
看下圖:
image.png
image.png
對比上面兩附圖碉输,為什么結(jié)果不同?亭珍?敷钾?
首先,在運行前肄梨,將變量提升阻荒,則第一幅圖可以等價于:
var a
a = {self:a} //此時在heap中寫“=”右邊的對象時,a的值還是undefined
-
一個測試題
如下圖:
image.png
解析:當(dāng)運行a.x = a = {n:2};
時众羡,瀏覽器是先看左邊再看右邊的侨赡,然后再把右邊的東西傳給左邊的容器;也就是說先確定左邊是個什么東西,再確定右邊是個什么東西羊壹,然后從右邊開始往左邊塞東西蓖宦;首先,看“=”左邊的 a.x 時已經(jīng)明確了此時的a = ADDR 34油猫,然后在看中間的 a 明確了中間的a = ADDR 34稠茂,再然后看右邊的東西,發(fā)現(xiàn)右邊的是個匿名對象情妖,即在 Heap 里面創(chuàng)建這個對象睬关,這樣左、中鲫售、右都明確了共螺,然后再執(zhí)行a = {n:2};
時,a = ADDR 54情竹,然而藐不,之前的 a.x 的指向并不會再次變更,導(dǎo)致鍵值對 x:{n:2} 添加在 ADDR 34里面秦效。 -
垃圾回收
image.png
測試題:
var fn = function(){}
document.body.onclick = fn
fn = null
此時雏蛮,var fn = function(){} 里面的function(){} 是否是垃圾?阱州?挑秉?
那么,當(dāng)瀏覽器中的這個頁面關(guān)閉時苔货,var fn = function(){} 里面的function(){} 是否是垃圾犀概??
答:yes夜惭,頁面關(guān)閉時姻灶,即document = null,所以之前的functiong就沒有被引用了诈茧。除了IE6产喉;
在IE6中當(dāng)前頁面關(guān)閉,瀏覽器未關(guān)閉時敢会,var fn = function(){} 里面的function(){} 還會保留曾沈,這樣導(dǎo)致 內(nèi)存 會被浪費,解決方法:
window.onload = function(){
document.body.onclick = null;
.
.
.
有多少個就重新賦值 null 多少個
}
- 淺拷貝 & 深拷貝
-
深拷貝:
image.png -
淺拷貝:
image.png