詳解JavaScript基本類型和引用類型
一、值的類型
早在介紹JS的數(shù)據(jù)類型的時(shí)候就提到過基本類型和引用類型,不過在說兩種類型之前,我們先來了解一下變量的值的類型。在ECMAScript中,變量可以存在兩種類型的值,即原始值和引用值。
(1)原始值
存儲(chǔ)在棧中的簡(jiǎn)單數(shù)據(jù)段,也就是說,它們的值直接存儲(chǔ)在變量訪問的位置。
(2)引用值
存儲(chǔ)在堆中的對(duì)象,也就是說,存儲(chǔ)在變量處的值是一個(gè)指針,指向存儲(chǔ)對(duì)象的內(nèi)存處。
為變量賦值時(shí),ECMAScript的解釋程序必須判斷該值是原始類型,還是引用類型。要實(shí)現(xiàn)這一點(diǎn),解釋程序則需嘗試判斷該值是否為ECMAScript的基本類型之一,即Undefined類型、Null類型、Boolean類型、Number類型和String類型。由于這些基本類型占據(jù)的空間是固定的,所以可將他們存儲(chǔ)在較小的內(nèi)存區(qū)域 - 棧中。這樣存儲(chǔ)便于迅速查尋變量的值。
在許多語言中,字符串都被看作引用類型,而非基本類型,因?yàn)樽址拈L(zhǎng)度是可變的。ECMAScript打破了這一
傳統(tǒng)。
如果一個(gè)值是引用類型的,那么它的存儲(chǔ)空間將從堆中分配。由于引用值的大小會(huì)改變,所以不能把它放在棧中,否則會(huì)降低變量查尋的速度。相反,放在變量的??臻g中的值是該對(duì)象存儲(chǔ)在堆中的地址。地址的大小是固定的,所以把它存儲(chǔ)在棧中對(duì)變量性能無任何負(fù)面影響。如下圖所示:
二、基本類型
ECMAScript有5種基本類型,即Undefined類型、Null類型、Boolean類型、Number類型和String類型。ECMA-262把術(shù)語類型定義為值的一個(gè)集合,每種基本類型定義了它包含的值的范圍及其字面量表示形式。
ECMAScript提供了typeof運(yùn)算符來判斷一個(gè)值是否在某種類型的范圍內(nèi)??梢杂眠@種運(yùn)算符判斷一個(gè)值是否表示一種基本類型:如果它是基本類型,還可以判斷它表示哪種基本類型。
基本數(shù)據(jù)類型和操作符typeof我們?cè)谇懊娴牟┪闹幸步?jīng)常使用到。詳細(xì)了解的話可以參考這篇文章:詳解JavaScript的變量和數(shù)據(jù)類型。
三、類型轉(zhuǎn)換
所有程序設(shè)計(jì)語言最重要的特征之一是具有進(jìn)行類型轉(zhuǎn)換的能力。ECMAScript給開發(fā)者提供了大量簡(jiǎn)單的類型轉(zhuǎn)換方法。大部分類型具有進(jìn)行簡(jiǎn)單轉(zhuǎn)換的方法,還有幾個(gè)全局方法可以用于更復(fù)雜的轉(zhuǎn)換。無論哪種情況,在ECMAScript中,類型轉(zhuǎn)換都是簡(jiǎn)短的一步操作。
(1)轉(zhuǎn)換成字符串
ECMAScript的Boolean值、數(shù)字和字符串的原始值的有趣之處在于它們是偽對(duì)象,這意味著它們實(shí)際上具有屬性和方法。
例如,要獲得字符串的長(zhǎng)度,可以采用下面的代碼:
var sbox = "red"; document.write(sbox.length);//輸出3
盡管 "red" 是基本類型的字符串,它仍然具有屬性length,用于存放字符串的大小??偠灾?,3 種主要的原始類型Boolean 值、數(shù)字和字符串都有 toString() 方法,可以把它們的值轉(zhuǎn)換成字符串。您也許會(huì)問,“字符串還有toString()方法嗎,這不是多余嗎?”是的,的確如此,不過ECMAScript定義所有對(duì)象都有toString()方法,無論它是偽對(duì)象,還是真對(duì)象。因?yàn)镾tring類型屬于偽對(duì)象,所以它一定有toString()方法。
1)Boolean 類型的toString()方法只是輸出 "true" 或 "false",結(jié)果由變量的值決定:
var bage=false; document.write(bage.toString());//輸出"false"
2)Number類型的toString()方法比較特殊,它有兩種模式,即默認(rèn)模式和基模式。采用默認(rèn)模式,toString()方法只是用相應(yīng)的字符串輸出數(shù)字值(無論是整數(shù)、浮點(diǎn)數(shù)還是科學(xué)計(jì)數(shù)法),在默認(rèn)模式中,無論最初采用什么表示法聲明數(shù)字,Number 類型的 toString() 方法返回的都是數(shù)字的十進(jìn)制表示。因此,以八進(jìn)制或十六進(jìn)制字面量形式聲明的數(shù)字輸出的都是十進(jìn)制形式的。如下所示:
var iNum1 = 10; var iNum2 = 10.0; document.write(iNum1.toString());//輸出 "10" document.write(iNum2.toString());//輸出 "10"
采用Number類型的 toString()方法的基模式,可以用不同的基輸出數(shù)字,例如二進(jìn)制的基是2,八進(jìn)制的基是8,十六進(jìn)制的基是16。
基只是要轉(zhuǎn)換成的基數(shù)的另一種加法而已,它是 toString() 方法的參數(shù):
var iNum = 10; document.write(iNum.toString(2));//輸出 "1010" document.write(iNum.toString(8));//輸出 "12" document.write(iNum.toString(16));//輸出 "a"
(2)轉(zhuǎn)換成數(shù)字
ECMAScript提供了兩種把非數(shù)字的原始值轉(zhuǎn)換成數(shù)字的方法,即parseInt()和parseFloat()。前者把值轉(zhuǎn)換成整數(shù),后者把值轉(zhuǎn)換成浮點(diǎn)數(shù)。只有對(duì)String類型調(diào)用這些方法,它們才能正確運(yùn)行;對(duì)其他類型返回的都是NaN。
1)parseInt()
在判斷字符串是否是數(shù)字值前,parseInt()和 parseFloat()都會(huì)仔細(xì)分析該字符串。parseInt()方法首先查看位置0處的字符,判斷它是否是個(gè)有效數(shù)字;如果不是,該方法將返回NaN,不再繼續(xù)執(zhí)行其他操作。但如果該字符是有效數(shù)字,該方法將查看位置1處的字符,進(jìn)行同樣的測(cè)試。這一過程將持續(xù)到發(fā)現(xiàn)非有效數(shù)字的字符為止,此時(shí)parseInt()將把該字符之前的字符串轉(zhuǎn)換成數(shù)字。
例如,如果要把字符串 "12345red" 轉(zhuǎn)換成整數(shù),那么parseInt()將返回12345,因?yàn)楫?dāng)它檢查到字符r 時(shí),就會(huì)停止檢測(cè)過程。
字符串中包含的數(shù)字字面量會(huì)被正確轉(zhuǎn)換為數(shù)字,比如 "0xA" 會(huì)被正確轉(zhuǎn)換為數(shù)字10。不過,字符串 "22.5" 將被轉(zhuǎn)換成22,因?yàn)閷?duì)于整數(shù)來說,小數(shù)點(diǎn)是無效字符。
var iNum1 = parseInt("12345red"); var iNum2 = parseInt("0xA"); var iNum3 = parseInt("56.9"); var iNum4 = parseInt("red"); document.write("iNum1="+iNum1);//返回12345 document.write("iNum2="+iNum2);//返回10 document.write("iNum3="+iNum3);//返回56 document.write("iNum3="+iNum4);//返回NaN
parseInt()方法還有基模式,可以把二進(jìn)制、八進(jìn)制、十六進(jìn)制或其他任何進(jìn)制的字符串轉(zhuǎn)換成整數(shù)?;怯蓀arseInt()方法的第二個(gè)參數(shù)指定的。
var iNum1 = parseInt("AF", 16); var iNum2 = parseInt("10", 2); var iNum3 = parseInt("10", 8); var iNum4 = parseInt("10", 10); document.write("iNum1="+iNum1);//返回175 document.write("iNum2="+iNum2);//返回2 document.write("iNum3="+iNum3);//返回8 document.write("iNum4="+iNum4);//返回10
2)parseFloat()方法
parseFloat()方法與parseInt()方法的處理方式相似,從位置0開始查看每個(gè)字符,直到找到第一個(gè)非有效的字符為止,然后把該字符之前的字符串轉(zhuǎn)換成整數(shù)。不過,對(duì)于這個(gè)方法來說,第一個(gè)出現(xiàn)的小數(shù)點(diǎn)是有效字符。如果有兩個(gè)小數(shù)點(diǎn),第二個(gè)小數(shù)點(diǎn)將被看作無效的。parseFloat()會(huì)把這個(gè)小數(shù)點(diǎn)之前的字符轉(zhuǎn)換成數(shù)字。這意味著字符串"11.22.33"將被解析成11.22。
使用parseFloat()方法的另一不同之處在于,字符串必須以十進(jìn)制形式表示浮點(diǎn)數(shù),而不是用八進(jìn)制或十六進(jìn)制。該方法會(huì)忽略前導(dǎo)0,所以八進(jìn)制數(shù)0102 將被解析為102。對(duì)于十六進(jìn)制數(shù)0xA,該方法將返回 NaN,因?yàn)樵诟↑c(diǎn)數(shù)中,x不是有效字符。此外,parseFloat() 方法也沒有基模式。
下面是使用 parseFloat() 方法的一些示例:
var fNum1 = parseFloat("12345red"); var fNum2 = parseFloat("0xA"); var fNum3 = parseFloat("11.2"); var fNum4 = parseFloat("11.22.33"); var fNum5 = parseFloat("0102"); var fNum6 = parseFloat("red"); document.write("iNum1="+iNum1);//返回12345 document.write("iNum2="+iNum2);//返回NaN document.write("iNum3="+iNum3);//返回11.2 document.write("iNum4="+iNum4);//返回11.22 document.write("iNum5="+iNum5);//返回102 document.write("iNum6="+iNum6);//返回NaN
(3)強(qiáng)制類型轉(zhuǎn)換
使用強(qiáng)制類型轉(zhuǎn)換來處理轉(zhuǎn)換值的類型。使用強(qiáng)制類型轉(zhuǎn)換可以訪問特定的值,即使它是另一種類型的。ECMAScript 中可用的3種強(qiáng)制類型轉(zhuǎn)換如下:
- 1)Boolean(value) - 把給定的值轉(zhuǎn)換成 Boolean 型;
- 2)Number(value) - 把給定的值轉(zhuǎn)換成數(shù)字(可以是整數(shù)或浮點(diǎn)數(shù));
- 3)String(value) - 把給定的值轉(zhuǎn)換成字符串;
這些應(yīng)該很好理解,在學(xué)習(xí)那些高級(jí)程序設(shè)計(jì)語言的時(shí)候經(jīng)常會(huì)能使用到這些。
四、引用類型
引用類型通常叫做類,也就是說,遇到引用值,所處理的就是對(duì)象。從傳統(tǒng)意義上來說,ECMAScript并不真正具有類。事實(shí)上,除了說明不存在類,在ECMA-262中根本沒有出現(xiàn)“類”這個(gè)詞。ECMAScript定義了“對(duì)象定義”,邏輯上等價(jià)于其他程序設(shè)計(jì)語言中的類。
對(duì)于JS對(duì)象的詳細(xì)解釋在前面的博文中也有,參考:輕松學(xué)習(xí)JavaScript九:JavaScript對(duì)象和數(shù)組。
我們?cè)賮砹私庖粋€(gè)判斷引用類型的操作符instanceof,在使用typeof運(yùn)算符時(shí)采用引用類型存儲(chǔ)值會(huì)出現(xiàn)一個(gè)問題,無論引用的是什么類型的對(duì)象,它都返回 "object"。ECMAScript引入了另一個(gè)Java運(yùn)算符 instanceof 來解決這個(gè)問題。instanceof運(yùn)算符與typeof運(yùn)算符相似,用于識(shí)別正在處理的對(duì)象的類型。與typeof方法不同的是,instanceof方
法要求開發(fā)者明確地確認(rèn)對(duì)象為某特定類型。
例如:
var oStringObject = new String("hello world"); document.write(oStringObject instanceof String);//輸出 "true"
這段代碼問的是“變量oStringObject是否為 String 對(duì)象的實(shí)例?”oStringObject的確是 String對(duì)象的實(shí)例,因此結(jié)果是 "true"。盡管不像typeof方法那樣靈活,但是在typeof方法返回 "object" 的情況下,instanceof方法還是很有用的。
此外,ECMAScript還有偽對(duì)象一說,也就是其他的基本類型,使用new創(chuàng)建時(shí)也是可以作為對(duì)象的,比如:String對(duì)象,Boolean對(duì)象和Number對(duì)象。它們是基本類型的引用類型。詳細(xì)了解參考:ECMAScript引用類型。ECMAScript還包含了許多對(duì)象,本地對(duì)象,內(nèi)置對(duì)象和宿主對(duì)象。這些我們會(huì)在后面的面向?qū)ο蟮臅r(shí)候具體了解。
五、復(fù)制變量值
在變量復(fù)制方面,基本類型和引用類型有所不同,基本類型是復(fù)制的是值本身,而引用類型復(fù)制的是地址。
我們來看具體的實(shí)例:
var box="Lee"; var box2=box; box2="Amy";//重新賦值后,兩個(gè)基本類型變量操作時(shí)互不影響,還是保持各自的獨(dú)立性 document.write("box2="+box2+"<br/>"); document.write("box="+box);
輸出的結(jié)果為:Amy
Lee
var box=new Object(); box.name="Lee"; var box2=box;//把引用地址值復(fù)制給box2 box2.name="Amy";//重新賦值后,兩個(gè)引用類型都指向同一個(gè)對(duì)象。name屬性只要發(fā)生改變都會(huì)更改原值。 document.write(" box2.name="+box2.name+"<br/>"); document.write("box.name="+box.name);
輸出的結(jié)果為:Amy
Amy
以上就是關(guān)于JavaScript基本類型和引用類型的詳細(xì)介紹,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
js實(shí)現(xiàn)網(wǎng)頁(yè)收藏功能
這篇文章主要介紹了js實(shí)現(xiàn)動(dòng)態(tài)添加或刪除網(wǎng)址功能,以及js實(shí)現(xiàn)網(wǎng)頁(yè)收藏功能,感興趣的小伙伴們可以參考一下2015-12-12詳解JS截取字符串的三個(gè)方法substring,substr,slice
js中有三個(gè)截取字符的方法,分別是substring()、substr()、slice(),平時(shí)我們可能都用到過,但總是會(huì)對(duì)這些方法有點(diǎn)混淆。本文將詳細(xì)介紹一下這三者的區(qū)別,需要的可以參考一下2022-03-03微信小程序?qū)崿F(xiàn)拍照畫布指定區(qū)域生成圖片
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)拍照畫布指定區(qū)域生成圖片,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07JavaScript實(shí)現(xiàn)獲取設(shè)備網(wǎng)絡(luò)連接信息
作為前端開發(fā),做好用戶體驗(yàn)是很重要的,日常開發(fā)中我們經(jīng)??梢杂龅接脩艟W(wǎng)速慢導(dǎo)致靜態(tài)資源加載慢,從而給影響用戶體驗(yàn),所以本文來和大家分享一個(gè)有趣的API,可以實(shí)現(xiàn)獲取網(wǎng)絡(luò)信息2023-05-05IE6下javasc#ipt:void(0) 無效的解決方法
本篇文章主要是對(duì)IE6下javasc#ipt:void(0) 無效的解決方法進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2013-12-12JavaScript中使用Substring刪除字符串最后一個(gè)字符
刪除字符串最后一個(gè)字符的方法有很多,在本文將為大家介紹下js中的substring是如何做到的,需要的朋友可以參考下2013-11-11JavaScript oncopy事件用法實(shí)例解析
這篇文章主要介紹了JavaScript oncopy事件用法實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05bootstrap weebox 支持ajax的模態(tài)彈出框
本篇介紹的bootstrap weebox(支持ajax的模態(tài)彈出框),歷經(jīng)多次修改,目前版本已經(jīng)穩(wěn)定,整合了bootstrap的響應(yīng)式,界面簡(jiǎn)單,功能卻無比豐富,支持ajax、圖片預(yù)覽等等2017-02-02基于JS實(shí)現(xiàn)回到頁(yè)面頂部的五種寫法(從實(shí)現(xiàn)到增強(qiáng))
這篇文章主要介紹了基于JS實(shí)現(xiàn)回到頁(yè)面頂部的五種寫法(從實(shí)現(xiàn)到增強(qiáng))的相關(guān)資料,本文介紹的非常詳細(xì),實(shí)用性也非常高,非常具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09