1朱监、基本數(shù)據(jù)類型和引用數(shù)據(jù)類型
ECMAScript包括兩個(gè)不同類型的值:基本數(shù)據(jù)類型和引用數(shù)據(jù)類型饭豹。
基本數(shù)據(jù)類型指的是簡(jiǎn)單的數(shù)據(jù)段没佑,引用數(shù)據(jù)類型指的是有多個(gè)值構(gòu)成的對(duì)象毕贼。
當(dāng)我們把變量賦值給一個(gè)變量時(shí),解析器首先要確認(rèn)的就是這個(gè)值是基本類型值還是引用類型值蛤奢。
2鬼癣、常見的基本數(shù)據(jù)類型:
Number陶贼、String 、Boolean待秃、Null和Undefined拜秧。基本數(shù)據(jù)類型是按值訪問的章郁,因?yàn)榭梢灾苯硬僮鞅4嬖谧兞恐械膶?shí)際值枉氮。示例:
var a = 10;
var b = a;
b = 20;
console.log(a); // 10值
上面,b獲取的是a值得一份拷貝暖庄,雖然聊替,兩個(gè)變量的值相等,但是兩個(gè)變量保存了兩個(gè)不同的基本數(shù)據(jù)類型值培廓。
b只是保存了a復(fù)制的一個(gè)副本惹悄。所以,b的改變肩钠,對(duì)a沒有影響泣港。
下圖演示了這種基本數(shù)據(jù)類型賦值的過程:
3、引用類型數(shù)據(jù):
也就是對(duì)象類型Object type蔬将,比如:Object 爷速、Array 、Function 霞怀、Data等惫东。
javascript的引用數(shù)據(jù)類型是保存在堆內(nèi)存中的對(duì)象。
與其他語言的不同是毙石,你不可以直接訪問堆內(nèi)存空間中的位置和操作堆內(nèi)存空間廉沮。只能操作對(duì)象在棧內(nèi)存中的引用地址。
所以徐矩,引用類型數(shù)據(jù)在棧內(nèi)存中保存的實(shí)際上是對(duì)象在堆內(nèi)存中的引用地址滞时。通過這個(gè)引用地址可以快速查找到保存中堆內(nèi)存中的對(duì)象。
var obj1 = new Object();
var obj2 = obj1;
obj2.name = "Tom";
console.log(obj1.name); // Tom
說明這兩個(gè)引用數(shù)據(jù)類型指向了同一個(gè)堆內(nèi)存對(duì)象滤灯。obj1賦值給obj2坪稽,實(shí)際上這個(gè)堆內(nèi)存對(duì)象在棧內(nèi)存的引用地址復(fù)制了一份給了obj2,
但是實(shí)際上他們共同指向了同一個(gè)堆內(nèi)存對(duì)象鳞骤。實(shí)際上改變的是堆內(nèi)存對(duì)象窒百。
下面我們來演示這個(gè)引用數(shù)據(jù)類型賦值過程:
4、總結(jié)區(qū)別
a 聲明變量時(shí)不同的內(nèi)存分配:
1)原始值:存儲(chǔ)在棧(stack)中的簡(jiǎn)單數(shù)據(jù)段豫尽,也就是說篙梢,它們的值直接存儲(chǔ)在變量訪問的位置。
這是因?yàn)檫@些原始類型占據(jù)的空間是固定的美旧,所以可將他們存儲(chǔ)在較小的內(nèi)存區(qū)域 – 棧中渤滞。這樣存儲(chǔ)便于迅速查尋變量的值贬墩。
2)引用值:存儲(chǔ)在堆(heap)中的對(duì)象,也就是說妄呕,存儲(chǔ)在變量處的值是一個(gè)指針(point)陶舞,指向存儲(chǔ)對(duì)象的內(nèi)存地址。
這是因?yàn)椋阂弥档拇笮?huì)改變绪励,所以不能把它放在棧中吊说,否則會(huì)降低變量查尋的速度。相反优炬,放在變量的棧空間中的值是該對(duì)象存儲(chǔ)在堆中的地址厅贪。
地址的大小是固定的蠢护,所以把它存儲(chǔ)在棧中對(duì)變量性能無任何負(fù)面影響。
b不同的內(nèi)存分配機(jī)制也帶來了不同的訪問機(jī)制
1)在javascript中是不允許直接訪問保存在堆內(nèi)存中的對(duì)象的养涮,所以在訪問一個(gè)對(duì)象時(shí)葵硕,
首先得到的是這個(gè)對(duì)象在堆內(nèi)存中的地址,然后再按照這個(gè)地址去獲得這個(gè)對(duì)象中的值贯吓,這就是傳說中的按引用訪問懈凹。
2)而原始類型的值則是可以直接訪問到的。
c 復(fù)制變量時(shí)的不同
1)原始值:在將一個(gè)保存著原始值的變量復(fù)制給另一個(gè)變量時(shí)悄谐,會(huì)將原始值的副本賦值給新變量介评,此后這兩個(gè)變量是完全獨(dú)立的,他們只是擁有相同的value而已爬舰。
2)引用值:在將一個(gè)保存著對(duì)象內(nèi)存地址的變量復(fù)制給另一個(gè)變量時(shí)们陆,會(huì)把這個(gè)內(nèi)存地址賦值給新變量,
也就是說這兩個(gè)變量都指向了堆內(nèi)存中的同一個(gè)對(duì)象情屹,他們中任何一個(gè)作出的改變都會(huì)反映在另一個(gè)身上坪仇。
(這里要理解的一點(diǎn)就是,復(fù)制對(duì)象時(shí)并不會(huì)在堆內(nèi)存中新生成一個(gè)一模一樣的對(duì)象垃你,只是多了一個(gè)保存指向這個(gè)對(duì)象指針的變量罷了)椅文。多了一個(gè)指針
d?參數(shù)傳遞的不同(把實(shí)參復(fù)制給形參的過程)
首先我們應(yīng)該明確一點(diǎn):ECMAScript中所有函數(shù)的參數(shù)都是按值來傳遞的。
但是為什么涉及到原始類型與引用類型的值時(shí)仍然有區(qū)別呢惜颇?還不就是因?yàn)閮?nèi)存分配時(shí)的差別皆刺。
1)原始值:只是把變量里的值傳遞給參數(shù),之后參數(shù)和這個(gè)變量互不影響官还。
2)引用值:對(duì)象變量它里面的值是這個(gè)對(duì)象在堆內(nèi)存中的內(nèi)存地址芹橡,這一點(diǎn)你要時(shí)刻銘記在心!
因此它傳遞的值也就是這個(gè)內(nèi)存地址望伦,這也就是為什么函數(shù)內(nèi)部對(duì)這個(gè)參數(shù)的修改會(huì)體現(xiàn)在外部的原因了林说,因?yàn)樗鼈兌贾赶蛲粋€(gè)對(duì)象煎殷。