您好,登錄后才能下訂單哦!
這篇文章主要講解了“javaScript引用類型與基本類型有哪些”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“javaScript引用類型與基本類型有哪些”吧!
1. 概念:
基本類型也叫簡單類型,存儲(chǔ)的數(shù)據(jù)是單一的,如:學(xué)生的個(gè)數(shù)就是一個(gè)數(shù)字而已;引用類型也叫復(fù)雜類型,存儲(chǔ)的數(shù)據(jù)是復(fù)雜的,如:學(xué)生,包括學(xué)號(hào),姓名,性別,年齡等等很多信息。從內(nèi)存(大家如果不懂內(nèi)存,請查閱相關(guān)資料)的角度來說:基本類型只占用一塊內(nèi)存區(qū)域;引用類型占用兩塊內(nèi)存區(qū)域。即定義基本類型的變量時(shí),在內(nèi)存中只申請一塊空間,變量的值直接存放在該空間;定義引用類型的變量時(shí)(容易理解的是,我門看到new運(yùn)算符,一般就是定義引用類型的變量),在內(nèi)存中申請兩塊空間,第一塊空間存儲(chǔ)的是第二塊空間的地址,第二塊空間存儲(chǔ)的是真正的數(shù)據(jù);第一塊空間叫作第二塊空間的引用(地址),所以叫作引用類型。
javaScript中的基本類型包括:數(shù)字(Number),字符串(String),布爾(Boolean),Null,Undefined五種;
javascript的引用類型是:Object。而Array,Date是屬于Obejct類型。
2. 內(nèi)存圖:
如下代碼(都是定義了兩個(gè)局部變量):
function demoFun(){
var num = 20;//定義了一個(gè)基本類型的變量。
var arr = new Array(12,23,34);//定義了一個(gè)引用類型的變量
}
以上兩行代碼的內(nèi)存圖:
可以看到,num變量只占用了一塊內(nèi)存區(qū)域;arr變量占用了兩塊內(nèi)存區(qū)域,arr變量在棧區(qū)(不懂棧區(qū)的人,先不要想太多)申請了一塊內(nèi)存區(qū)域,存儲(chǔ)著地址,存儲(chǔ)的地址是堆區(qū)的地址。而堆區(qū)中真正才存儲(chǔ)著數(shù)據(jù),所以說,arr變量占用了兩塊內(nèi)存區(qū)域。這樣看來,引用類型的變量好像還占用內(nèi)存多了。哈哈,不要著急,后面了解了引用類型的優(yōu)點(diǎn)后,你就會(huì)覺得這是問題了。
當(dāng)我們讀取num變量的值時(shí),直接就能讀到,但是當(dāng)我們要讀取arr里的值時(shí),先找到arr中的地址,然后根據(jù)地址再找到對(duì)應(yīng)的數(shù)據(jù)。
引用類型,類似于windows操作系統(tǒng)中的快捷方式??旖莘绞骄褪且粋€(gè)地址,真正的內(nèi)容是快捷方式所指向的路徑的內(nèi)容。如:我們把d:\t.txt文件創(chuàng)建一個(gè)快捷方式放在桌面上,那么,桌面上的快捷方式會(huì)占用桌面的空間,而d:\t.txt會(huì)占用d盤的空間,所以,占用了兩塊空間。
基本類型就相當(dāng)于文件。
引用類型,類似于我們在入學(xué)報(bào)名填寫報(bào)名表時(shí),填寫家庭地址,這個(gè)家庭地址就相當(dāng)于第一塊空間,真正你家(第二塊內(nèi)存空間)不在報(bào)名表上。學(xué)校要找你家,先在報(bào)名表上找到你家的地址,然后根據(jù)地址,才能找到你家去。
3. 引用類型的優(yōu)點(diǎn):
引用類型作為函數(shù)的參數(shù)時(shí),優(yōu)點(diǎn)特別明顯,第一,形參傳遞給實(shí)參時(shí),只需要傳遞地址,而不需要搬動(dòng)大量的數(shù)據(jù)(節(jié)約了內(nèi)存開銷);第二,形參對(duì)應(yīng)的數(shù)據(jù)改變時(shí),實(shí)參對(duì)應(yīng)的數(shù)據(jù)也在改變(很多時(shí)候,我們希望這樣)。
如以下代碼:
先定義函數(shù)(冒泡排序)
function bubble(arr){
for(var i=0;i
for(var j=0;j
if(arr[j]>arr[j+1]){
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
當(dāng)調(diào)用冒泡排序時(shí),
var arr1 = [250,2,290,35,12,99];
bubble(arr1);
看看內(nèi)存以上代碼執(zhí)行時(shí)的,內(nèi)存變化:
圖中,當(dāng)執(zhí)行,①對(duì)應(yīng)的代碼(var arr1 = [250,2,290,35,12,99];)時(shí),內(nèi)存中會(huì)產(chǎn)生①對(duì)應(yīng)的變化,即在棧中申請一塊內(nèi)存區(qū)域,起名為arr1,在堆區(qū)中申請內(nèi)存空間放置250,2,290,35,12,99,并把堆區(qū)中的內(nèi)存的地址賦給arr1的內(nèi)存中;當(dāng)執(zhí)行②對(duì)應(yīng)的代碼bubble(arr1)時(shí),調(diào)用函數(shù)。這時(shí)候會(huì)定義形參arr(內(nèi)存中③對(duì)應(yīng)的變化),即在棧中申請一塊內(nèi)存區(qū)域,起名為arr,并把a(bǔ)rr1保存的地址賦給了arr(內(nèi)存中②表示的賦值),這樣,形參arr和實(shí)參arr1就指向了同一塊內(nèi)存區(qū)域。數(shù)組中的值250,2,290,35,12,99在內(nèi)存中只有一份。即,不用把數(shù)組中每個(gè)元素的值再復(fù)制一份,節(jié)約了內(nèi)存。如果對(duì)內(nèi)存圖看懂了,那么,當(dāng)形參arr對(duì)應(yīng)的數(shù)據(jù)順序改變了,實(shí)參arr1對(duì)應(yīng)的數(shù)據(jù)順序也就改變了。即,實(shí)現(xiàn)了形參數(shù)據(jù)改變時(shí),實(shí)參數(shù)據(jù)也改變了。所以,bubble函數(shù)不需要返回值,依然可以達(dá)到排序的目的??梢赃\(yùn)行我示例中的代碼,看看是不是達(dá)到了排序的效果。
補(bǔ)充,基本類型作為函數(shù)參數(shù)的內(nèi)存變化:
內(nèi)存圖:
4. 引用類型變量的賦值:
引用類型變量賦值時(shí),賦的是地址。即兩個(gè)引用類型變量里存儲(chǔ)的是同一塊地址,也就是說,兩個(gè)引用類型變量都指向同一塊內(nèi)存區(qū)域。所以,兩個(gè)引用類型變量對(duì)應(yīng)的數(shù)據(jù)時(shí)一樣的。
再如:
var person1 = {
name:"張三",
sex:"男",
age:12
};
var person2 = person1;
person2.name="張四"; //這句話會(huì)改變person1和person2的name。說明person1和person2的name占用的是同一塊內(nèi)存。
alert(person1.name+","+person1.sex+","+person1.age);
alert(person2.name+","+person2.sex+","+person2.age);
基本類型變量賦值時(shí)的內(nèi)存變化。
5. 淺拷貝和深拷貝
先說對(duì)象的復(fù)制,上面說了,引用類型(對(duì)象)的賦值,只是賦的地址,那么要真正復(fù)制一份新的對(duì)象(即克隆)時(shí),又該怎么辦。
var person1 = {
name:"張三",
sex:"男",
age:12
};
var person2={};
for(var key in person1){
person2[key] = person1[key];
}
但是,當(dāng)一個(gè)對(duì)象的屬性又是一個(gè)引用類型時(shí),會(huì)出現(xiàn)淺拷貝和深拷貝的問題。用一個(gè)自定義的object類型來說明問題。
如:
var person1 = {
name:"張三",
sex:"男",
age:12,
address:{
country:"陜西",
city:"渭南"
}
};
//對(duì)象person1的address又是個(gè)對(duì)象,即,要對(duì)person1做真正的克隆,需要把a(bǔ)ddress中的每個(gè)屬性也進(jìn)行克隆。
var person2={};
for(var key in person1){
person2[key] = person1[key];
}
person2.name="張四"; //不會(huì)改變掉person1的name屬性。
person2.address.country="北京";//會(huì)改變掉person1的address.country
大家注意看,person1和person2的name屬性各有各的空間,但是person1.address.country和person2.address.country是同一塊空間。所以,改變person2.address.country的值時(shí),person1.address.country的值也會(huì)改變。這就說明拷貝(克隆)的不到位,這種拷貝叫作淺拷貝,而進(jìn)一步把person1.address.country和person1.address.name也拷貝(克隆)了,就是深拷貝。要做到深拷貝,就需要對(duì)每個(gè)屬性的類型進(jìn)行判斷,如果是引用類型,就再循環(huán)進(jìn)行拷貝(需要用到遞歸)。
感謝各位的閱讀,以上就是“javaScript引用類型與基本類型有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)javaScript引用類型與基本類型有哪些這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。