21-進(jìn)階 JS里的類型

  • 類型轉(zhuǎn)換

  1. 轉(zhuǎn)換為string、boolean
image.png

類型轉(zhuǎn)換中的一些特殊情況:

  • 其他類型轉(zhuǎn)換為boolean時(shí)為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
  1. 轉(zhuǎn)換為number

一般情況下,只會(huì)將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()會(huì)從左往右開始轉(zhuǎn)換遇到的數(shù)字,直到非數(shù)字就結(jié)束。

  • 內(nèi)存圖

此處,只通過以下幾張圖簡單了解JS的在所分配的內(nèi)存中的一些存儲過程。

  1. 內(nèi)存分配簡圖


    js-21-01.png

    內(nèi)存是讀寫速度最快的,當(dāng)前運(yùn)行的程序都會(huì)拷貝到內(nèi)存中運(yùn)行。開機(jī)就是將操作系統(tǒng)讀取到內(nèi)存中運(yùn)行。

  2. 假定瀏覽器給JS分配了100M內(nèi)存,那JS是如何使用的??
    js-21-02.png

    JS會(huì)將分到的內(nèi)存劃分為代碼區(qū)和數(shù)據(jù)區(qū),比如代碼var a=1;,a 就存在代碼區(qū),數(shù)字1則存在數(shù)據(jù)區(qū),兩者之間會(huì)有某種關(guān)聯(lián)。
  3. 數(shù)據(jù)區(qū)又是如何存儲的??


    js-21-03.png

    數(shù)據(jù)區(qū)會(huì)劃分為2塊,棧內(nèi)存和堆內(nèi)存;
    當(dāng)瀏覽器開始運(yùn)行代碼區(qū)的代碼時(shí),第一步首先是:變量提升;之后才開始運(yùn)行,運(yùn)行時(shí)也就開始將數(shù)據(jù)存儲在數(shù)據(jù)區(qū);

js-21-04.png

如上圖,數(shù)字1、2、.......在JS中都是以固定的64位2進(jìn)制來存儲的,然而其他內(nèi)型并不都是按固定長度二進(jìn)制來存儲的,那么如圖:如果隨著運(yùn)行按順序存儲每一步的數(shù)據(jù),當(dāng)給 對象 o 增加新的鍵值對時(shí),就需要在第一次存 o 的位置插入一段空間,這就很尷尬了...............

因此實(shí)際存儲時(shí),根據(jù)數(shù)據(jù)類型荀澤對應(yīng)的存儲區(qū):


image.png

如上圖,實(shí)際對對象 o 的存儲是分2部分的,棧內(nèi)存中存的是一個(gè)地址,這個(gè)地址指向堆內(nèi)存中存放具體數(shù)據(jù)的一段空間。

當(dāng)執(zhí)行o2 = o;,時(shí):

image.png

會(huì)將棧內(nèi)存中 o 的數(shù)據(jù)(即地址)拷給 o2 ,之后 o 和 o2 實(shí)際指向堆內(nèi)存中同一空間。也就是說 “=”實(shí)際只在棧內(nèi)存中操作。“=”只是把右邊的對應(yīng)的東西放到左邊的對應(yīng)的空間里。

  1. JS中7種數(shù)據(jù)類型的存儲方式


    image.png

    對于6種簡單類型,直接存在stack中,關(guān)于string此處暫不討論;
    對于Object類型,存在stack中的是對應(yīng)的heap中的一個(gè)空間的地址,也就是Object的實(shí)際內(nèi)容是存儲在heap中,因此Object是對heap中一段空間的引用。

  2. 幾個(gè)案例

  • 如下圖:


    image.png
  • 如下圖:


    image.png

    首先,回顧這一句:“=”只是把右邊的對應(yīng)的東西放到左邊的對應(yīng)的空間里。左邊是b,那么b對應(yīng)的空間是???
    b對應(yīng)的空間是: stack 給b分配的一小段空間;而右邊的是一個(gè)匿名 對象 ,首先給匿名對象在 heap 分配一個(gè)空間存放內(nèi)容;之后再執(zhí)行“=”。

  • 如下圖:


    image.png

    b.name對應(yīng)的空間是: b在stack里存的地址所指向的heap中的一個(gè)空間里的名為“name”的key所對應(yīng)的空間;而右邊的是一個(gè)字符串 ,字符串是簡單類型;直接執(zhí)行“=”。

  • 如下圖:


    image.png
  1. 關(guān)于對象里的self
    看下圖:


    image.png

    image.png

    對比上面兩附圖,為什么結(jié)果不同???
    首先,在運(yùn)行前,將變量提升,則第一幅圖可以等價(jià)于:

var a
a = {self:a}  //此時(shí)在heap中寫“=”右邊的對象時(shí),a的值還是undefined
  1. 一個(gè)測試題
    如下圖:

    image.png

    解析:當(dāng)運(yùn)行a.x = a = {n:2};時(shí),瀏覽器是先看左邊再看右邊的,然后再把右邊的東西傳給左邊的容器;也就是說先確定左邊是個(gè)什么東西,再確定右邊是個(gè)什么東西,然后從右邊開始往左邊塞東西;首先,看“=”左邊的 a.x 時(shí)已經(jīng)明確了此時(shí)的a = ADDR 34,然后在看中間的 a 明確了中間的a = ADDR 34,再然后看右邊的東西,發(fā)現(xiàn)右邊的是個(gè)匿名對象,即在 Heap 里面創(chuàng)建這個(gè)對象,這樣左、中、右都明確了,然后再執(zhí)行a = {n:2};時(shí),a = ADDR 54,然而,之前的 a.x 的指向并不會(huì)再次變更,導(dǎo)致鍵值對 x:{n:2} 添加在 ADDR 34里面。

  2. 垃圾回收


    image.png

測試題:

var fn = function(){}
document.body.onclick = fn
fn = null
此時(shí),var fn = function(){} 里面的function(){} 是否是垃圾???
image.png

那么,當(dāng)瀏覽器中的這個(gè)頁面關(guān)閉時(shí),var fn = function(){} 里面的function(){} 是否是垃圾??
答:yes,頁面關(guān)閉時(shí),即document = null,所以之前的functiong就沒有被引用了。除了IE6;
在IE6中當(dāng)前頁面關(guān)閉,瀏覽器未關(guān)閉時(shí),var fn = function(){} 里面的function(){} 還會(huì)保留,這樣導(dǎo)致 內(nèi)存 會(huì)被浪費(fèi),解決方法:


image.png
window.onload = function(){
    document.body.onclick = null;
    .
    .
    .
    有多少個(gè)就重新賦值 null 多少個(gè)
}
  1. 淺拷貝 & 深拷貝
  • 深拷貝:


    image.png
  • 淺拷貝:


    image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容