javascript中有哪些數(shù)據(jù)類型-創(chuàng)新互聯(lián)

這篇文章給大家分享的是有關(guān)javascript中有哪些數(shù)據(jù)類型的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比依安網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式依安網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋依安地區(qū)。費(fèi)用合理售后完善,10年實(shí)體公司更值得信賴。

js基本七種數(shù)據(jù)類型為:1、String類型,用于表示字符串;2、Number類型,用于表示數(shù)字;3、Boolean類型;4、Symbol類型,代表獨(dú)一無(wú)二的值;5、Undefined類型;6、Null類型;7、Object類型。

在 JavaScript 規(guī)范中,共定義了七種數(shù)據(jù)類型,分為 “基本類型” 和 “引用類型” 兩大類,如下所示:

  • 基本類型:String、Number、Boolean、Symbol、Undefined、Null
  • 引用類型:Object

下面將詳細(xì)介紹這七種數(shù)據(jù)類型的一些特性。

1、String 類型

String 類型用于表示由零或多個(gè) 16 位 Unicode 字符組成的字符序列,即字符串 。

1.1 存儲(chǔ)結(jié)構(gòu)

由于計(jì)算機(jī)只能處理數(shù)字,如果要處理文本,就必須先把文本轉(zhuǎn)換為數(shù)字才能處理。在計(jì)算機(jī)中,1個(gè)字節(jié)(byte)由 8個(gè)比特(bit)組成,所以 1 個(gè)字節(jié)能表示的較大整數(shù)就是 255,如果想表示更大整數(shù),就必須用更多的字節(jié),比如 2 個(gè)字節(jié)可以表示的較大整數(shù)為 65535 。最早,只有 127 個(gè)字符被編碼到計(jì)算機(jī)里,也就是大小寫(xiě)英文字母、數(shù)字和一些符號(hào),這個(gè)編碼表被稱為 ASCII編碼,比如大寫(xiě)字母 A 的編碼是 65,小寫(xiě)字母 z 的編碼是122。

但如果要表示中文字符,顯然一個(gè)字節(jié)是不夠的,至少需要兩個(gè)字節(jié)。所以,中國(guó)制定了 GB2312 編碼,用來(lái)表示中文字符?;谕瑯拥脑?,各個(gè)國(guó)家都制定了自己的編碼規(guī)則 。這樣就會(huì)出現(xiàn)一個(gè)問(wèn)題,即在多語(yǔ)言混合的文本中,不同的編碼會(huì)出現(xiàn)沖突,導(dǎo)致亂碼出現(xiàn) 。

為了解決這個(gè)問(wèn)題,Unicode 編碼應(yīng)運(yùn)而生,它把所有的語(yǔ)言都統(tǒng)一到一套編碼中,采用 2 個(gè)字節(jié)表示一個(gè)字符,即最多可以表示 65535 個(gè)字符,這樣基本上可以覆蓋世界上常用的文字,如果要表示更多的文字,也可以采用 4 個(gè)字節(jié)進(jìn)行編碼,這是一種通用的編碼規(guī)范 。

因此,JavaScript 中的字符也采用 Unicode 來(lái)編碼 ,也就是說(shuō),JavaScript 中的英文字符和中文字符都會(huì)占用 2 個(gè)字節(jié)的空間大小 ,這種多字節(jié)字符,通常被稱為寬字符。

1.2 基本包裝類型

在 JavaScript 中,字符串是基本數(shù)據(jù)類型,本身不存任何操作方法 。為了方便的對(duì)字符串進(jìn)行操作,ECMAScript 提供了一個(gè)基本包裝類型:String 對(duì)象 。它是一種特殊的引用類型,JS引擎每當(dāng)讀取一個(gè)字符串的時(shí)候,就會(huì)在內(nèi)部創(chuàng)建一個(gè)對(duì)應(yīng)的 String 對(duì)象,該對(duì)象提供了很多操作字符的方法,這就是為什么能對(duì)字符串調(diào)用方法的原因 。

var name = 'JavaScript';
var value = name.substr(2,1);

當(dāng)?shù)诙写a訪問(wèn)變量 str 時(shí),訪問(wèn)過(guò)程處于一種讀取模式,也就是要從內(nèi)存中讀取這個(gè)字符串的值。而在讀取模式中訪問(wèn)字符串時(shí),引擎內(nèi)部會(huì)自動(dòng)完成下列處理:

  • 創(chuàng)建 String 類型的一個(gè)實(shí)例
  • 在實(shí)例上調(diào)用指定的方法
  • 銷毀這個(gè)實(shí)例

用偽代碼形象的模擬以上三個(gè)步驟:

var obj = new String('JavaScript'); 
var value = obj.substr(2,1); 
name = null;

可以看出,基本包裝類型是一種特殊的引用類型。它和普通引用類型有一個(gè)很重要的區(qū)別,就是對(duì)象的生存期不同 。使用 new 操作符創(chuàng)建的引用類型的實(shí)例,在執(zhí)行流離開(kāi)當(dāng)前作用域之前都一直保存在內(nèi)存中。而自動(dòng)創(chuàng)建的基本包裝類型的對(duì)象,則只存在于一行代碼的執(zhí)行瞬間,然后立即被銷毀。在 JavaScript 中,類似的基本包裝類型還有 Number、Boolean 對(duì)象 。

1.3 常用操作方法

作為字符串的基本包裝類型,String 對(duì)象提供了以下幾類方法,用以操作字符串:

  • 字符操作:charAt,charCodeAt,fromCharCode
  • 字符串提?。簊ubstr,substring ,slice
  • 位置索引:indexOf ,lastIndexOf
  • 大小寫(xiě)轉(zhuǎn)換:toLowerCase,toUpperCase
  • 模式匹配:match,search,replace,split
  • 其他操作:concat,trim,localeCompare

charCodeAt 的作用是獲取字符的 Unicode 編碼,俗稱 “Unicode 碼點(diǎn)”。fromCharCode 是 String 對(duì)象上的靜態(tài)方法,作用是根據(jù) Unicode 編碼返回對(duì)應(yīng)的字符。

var a = 'a';
// 獲取Unicode編碼
var code = a.charCodeAt(0); // 97
// 根據(jù)Unicode編碼獲取字符
String.fromCharCode(code);  // a

通過(guò) charCodeAt 獲取字符的 Unicode 編碼,然后再把這個(gè)編碼轉(zhuǎn)化成二進(jìn)制,就可以得到該字符的二進(jìn)制表示。

var a = 'a';
var code = a.charCodeAt(0); // 97
code.toString(2); // 1100001

對(duì)于字符串的提取操作,有三個(gè)相類似的方法,分別如下:

substr(start [, length])
substring(start [, end])
slice(start [, end])

從定義上看,substring 和 slice 是同類的,參數(shù)都是字符串的某個(gè) start 位置到某個(gè) end 位置(但 end 位置的字符不包括在結(jié)果中);而 substr 則是字符串的某個(gè) start 位置起,數(shù) length 個(gè)長(zhǎng)度的字符才結(jié)束。二者的共性是:從 start 開(kāi)始,如果沒(méi)有第 2 個(gè)參數(shù),都是直到字符串末尾。

substring 和 slice 的區(qū)別則是:slice 可以接受 “負(fù)數(shù)”,表示從字符串尾部開(kāi)始計(jì)數(shù); 而 substring 則把負(fù)數(shù)或其它無(wú)效的數(shù)當(dāng)作 0。

'hello world!'.slice(-6, -1) // 'world'
'hello world!'.substring("abc", 5) // 'hello'

substr 的 start 也可接受負(fù)數(shù),也表示從字符串尾部計(jì)數(shù),這點(diǎn)和 slice 相同;但 substr 的 length 則不能小于 1,否則返回空字符串?! ?/p>

'hello world!'.substr(-6, 5) // 'world'
'hello world!'.substr(0, -1) // ''

2、Number 類型

JavaScript 中的數(shù)字類型只有 Number 一種,Number 類型采用 IEEE754 標(biāo)準(zhǔn)中的 “雙精度浮點(diǎn)數(shù)” 來(lái)表示一個(gè)數(shù)字,不區(qū)分整數(shù)和浮點(diǎn)數(shù) 。

2.1 存儲(chǔ)結(jié)構(gòu)

在 IEEE754 中,雙精度浮點(diǎn)數(shù)采用 64 位存儲(chǔ),即 8 個(gè)字節(jié)表示一個(gè)浮點(diǎn)數(shù) 。其存儲(chǔ)結(jié)構(gòu)如下圖所示:

javascript中有哪些數(shù)據(jù)類型

指數(shù)位可以通過(guò)下面的方法轉(zhuǎn)換為使用的指數(shù)值:

javascript中有哪些數(shù)據(jù)類型

2.2 數(shù)值范圍

從存儲(chǔ)結(jié)構(gòu)中可以看出, 指數(shù)部分的長(zhǎng)度是11個(gè)二進(jìn)制,即指數(shù)部分能表示的較大值是 2047(211-1),取中間值進(jìn)行偏移,用來(lái)表示負(fù)指數(shù),也就是說(shuō)指數(shù)的范圍是 [-1023,1024] 。因此,這種存儲(chǔ)結(jié)構(gòu)能夠表示的數(shù)值范圍為 21024到 2-1023,超出這個(gè)范圍的數(shù)無(wú)法表示 。21024 和 2-1023  轉(zhuǎn)換為科學(xué)計(jì)數(shù)法如下所示:

1.7976931348623157 × 10308

5 × 10-324

因此,JavaScript 中能表示的較大值是 1.7976931348623157 × 10308,最小值為 5 × 10-324 。

這兩個(gè)邊界值可以分別通過(guò)訪問(wèn) Number 對(duì)象的 MAX_VALUE 屬性和 MIN_VALUE 屬性來(lái)獲取:

Number.MAX_VALUE; // 1.7976931348623157e+308
Number.MIN_VALUE; // 5e-324

如果數(shù)字超過(guò)較大值或最小值,JavaScript 將返回一個(gè)不正確的值,這稱為 “正向溢出(overflow)” 或 “負(fù)向溢出(underflow)” 。

Number.MAX_VALUE+1 == Number.MAX_VALUE; //true
Number.MAX_VALUE+1e292; //Infinity
Number.MIN_VALUE + 1; //1
Number.MIN_VALUE - 3e-324; //0
Number.MIN_VALUE - 2e-324; //5e-324
2.3 數(shù)值精度

在 64 位的二進(jìn)制中,符號(hào)位決定了一個(gè)數(shù)的正負(fù),指數(shù)部分決定了數(shù)值的大小,小數(shù)部分決定了數(shù)值的精度。

IEEE754 規(guī)定,有效數(shù)字第一位默認(rèn)總是1 。因此,在表示精度的位數(shù)前面,還存在一個(gè) “隱藏位” ,固定為 1 ,但它不保存在 64 位浮點(diǎn)數(shù)之中。也就是說(shuō),有效數(shù)字總是 1.xx...xx 的形式,其中 xx..xx 的部分保存在 64 位浮點(diǎn)數(shù)之中,最長(zhǎng)為52位 。所以,JavaScript 提供的有效數(shù)字最長(zhǎng)為 53 個(gè)二進(jìn)制位,其內(nèi)部實(shí)際的表現(xiàn)形式為:

(-1)^符號(hào)位 * 1.xx...xx * 2^指數(shù)位

這意味著,JavaScript 能表示并進(jìn)行精確算術(shù)運(yùn)算的整數(shù)范圍為:[-253-1,253-1],即從最小值 -9007199254740991 到較大值 9007199254740991 之間的范圍 。

Math.pow(2, 53)-1 ; // 9007199254740991
-Math.pow(2, 53)-1 ; // -9007199254740991

可以通過(guò) Number.MAX_SAFE_INTEGER 和  Number.MIN_SAFE_INTEGER 來(lái)分別獲取這個(gè)較大值和最小值。

console.log(Number.MAX_SAFE_INTEGER) ; // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER) ; // -9007199254740991

對(duì)于超過(guò)這個(gè)范圍的整數(shù),JavaScript 依舊可以進(jìn)行運(yùn)算,但卻不保證運(yùn)算結(jié)果的精度。

Math.pow(2, 53) ; // 9007199254740992
Math.pow(2, 53) + 1; // 9007199254740992
9007199254740993; //9007199254740992
90071992547409921; //90071992547409920
0.923456789012345678;//0.9234567890123456
2.4 精度丟失

計(jì)算機(jī)中的數(shù)字都是以二進(jìn)制存儲(chǔ)的,如果要計(jì)算 0.1 + 0.2 的結(jié)果,計(jì)算機(jī)會(huì)先把 0.1 和 0.2 分別轉(zhuǎn)化成二進(jìn)制,然后相加,最后再把相加得到的結(jié)果轉(zhuǎn)為十進(jìn)制 。

但有一些浮點(diǎn)數(shù)在轉(zhuǎn)化為二進(jìn)制時(shí),會(huì)出現(xiàn)無(wú)限循環(huán) 。比如, 十進(jìn)制的 0.1 轉(zhuǎn)化為二進(jìn)制,會(huì)得到如下結(jié)果:

0.0001 1001 1001 1001 1001 1001 1001 1001 …(1001無(wú)限循環(huán))

而存儲(chǔ)結(jié)構(gòu)中的尾數(shù)部分最多只能表示 53 位。為了能表示 0.1,只能模仿十進(jìn)制進(jìn)行四舍五入了,但二進(jìn)制只有 0 和 1 , 于是變?yōu)?0 舍 1 入 。 因此,0.1 在計(jì)算機(jī)里的二進(jìn)制表示形式如下:

0.0001100110011001100110011001100110011001100110011001101

用標(biāo)準(zhǔn)計(jì)數(shù)法表示如下:

(?1)0× 2?4× (1.1001100110011001100110011001100110011001100110011010)2

同樣,0.2 的二進(jìn)制也可以表示為:

(?1)0× 2?3× (1.1001100110011001100110011001100110011001100110011010)2

在計(jì)算浮點(diǎn)數(shù)相加時(shí),需要先進(jìn)行 “對(duì)位”,將較小的指數(shù)化為較大的指數(shù),并將小數(shù)部分相應(yīng)右移:

0.1→ (?1)0× 2?3× (0.11001100110011001100110011001100110011001100110011010)2
0.2→ (?1)0× 2?3× (1.1001100110011001100110011001100110011001100110011010)2

最終,“0.1 + 0.2” 在計(jì)算機(jī)里的計(jì)算過(guò)程如下:

javascript中有哪些數(shù)據(jù)類型

經(jīng)過(guò)上面的計(jì)算過(guò)程,0.1 + 0.2 得到的結(jié)果也可以表示為:

(?1)0× 2?2× (1.0011001100110011001100110011001100110011001100110100)2

然后,通過(guò) JS 將這個(gè)二進(jìn)制結(jié)果轉(zhuǎn)化為十進(jìn)制表示:

(-1)**0 * 2**-2 * (0b10011001100110011001100110011001100110011001100110100 * 2**-52); //0.30000000000000004
console.log(0.1 + 0.2) ; // 0.30000000000000004

這是一個(gè)典型的精度丟失案例,從上面的計(jì)算過(guò)程可以看出,0.1 和 0.2 在轉(zhuǎn)換為二進(jìn)制時(shí)就發(fā)生了一次精度丟失,而對(duì)于計(jì)算后的二進(jìn)制又有一次精度丟失 。因此,得到的結(jié)果是不準(zhǔn)確的。

2.5 特殊數(shù)值

JavaScript 提供了幾個(gè)特殊數(shù)值,用于判斷數(shù)字的邊界和其他特性 。如下所示:

  • Number.MAX_VALUE:JavaScript 中的較大值
  • Number.MIN_VALUE:JavaScript 中的最小值
  • Number.MAX_SAFE_INTEGER:較大安全整數(shù),為 253-1
  • Number.MIN_SAFE_INTEGER:最小安全整數(shù),為 -(253-1)
  • Number.POSITIVE_INFINITY:對(duì)應(yīng) Infinity,代表正無(wú)窮
  • Number.NEGATIVE_INFINITY:對(duì)應(yīng) -Infinity,代表負(fù)無(wú)窮
  • Number.EPSILON:是一個(gè)極小的值,用于檢測(cè)計(jì)算結(jié)果是否在誤差范圍內(nèi)
  • Number.NaN:表示非數(shù)字,NaN與任何值都不相等,包括NaN本身
  • Infinity:表示無(wú)窮大,分 正無(wú)窮 Infinity 和 負(fù)無(wú)窮 -Infinity
2.6 數(shù)值轉(zhuǎn)換

有 3 個(gè)函數(shù)可以把非數(shù)值轉(zhuǎn)換為數(shù)值,分別如下:

Number(value)
parseInt(string [, radix])
parseFloat(string)

Number() 可以用于任何數(shù)據(jù)類型,而另兩個(gè)函數(shù)則專門(mén)用于把字符串轉(zhuǎn)換成數(shù)值。

對(duì)于字符串而言,Number() 只能對(duì)字符串進(jìn)行整體轉(zhuǎn)換,而 parseInt() 和 parseFloat() 可以對(duì)字符串進(jìn)行部分轉(zhuǎn)換,即只轉(zhuǎn)換第一個(gè)無(wú)效字符之前的字符。

對(duì)于不同數(shù)據(jù)類型的轉(zhuǎn)換,Number() 的處理也不盡相同,其轉(zhuǎn)換規(guī)則如下:

【1】如果是 Boolean 值,true 和 false 將分別被轉(zhuǎn)換為 1 和 0。

【2】如果是數(shù)字值,只是簡(jiǎn)單的傳入和返回。

【3】如果是 null 值,返回 0。

【4】如果是 undefined,返回 NaN。

【5】如果是字符串,遵循下列規(guī)則:

  • 如果字符串中只包含數(shù)字(包括前面帶正號(hào)或負(fù)號(hào)的情況),則將其轉(zhuǎn)換為十進(jìn)制數(shù)值;
  • 如果字符串中包含有效的浮點(diǎn)格式,則將其轉(zhuǎn)換為對(duì)應(yīng)的浮點(diǎn)數(shù)值;
  • 如果字符串中包含有效的十六進(jìn)制格式,則將其轉(zhuǎn)換為相同大小的十進(jìn)制整數(shù)值;
  • 如果字符串是空的(不包含任何字符),則將其轉(zhuǎn)換為 0;
  • 如果字符串中包含除上述格式之外的字符,則將其轉(zhuǎn)換為 NaN。

【6】如果是對(duì)象,則調(diào)用對(duì)象的 valueOf() 方法,然后依照前面的規(guī)則轉(zhuǎn)換返回的值。如果轉(zhuǎn)換的結(jié)果是 NaN,則調(diào)用對(duì)象的 toString() 方法,然后再次依照前面的規(guī)則轉(zhuǎn)換返回的字符串值。

需要注意的是:

一元加操作符加號(hào) “+” 和 Number() 具有同樣的作用。

在 ECMAScript 2015 規(guī)范中,為了實(shí)現(xiàn)全局模塊化,Number 對(duì)象重寫(xiě)了 parseInt 和 parseFloat 方法,但和對(duì)應(yīng)的全局方法并無(wú)區(qū)別。

Number.parseInt === parseInt; // true
Number.parseFloat === parseFloat; // true
2.7 位運(yùn)算

位運(yùn)算作用于最基本的層次上,即按內(nèi)存中表示數(shù)值的位來(lái)操作數(shù)值。ECMAScript 中的數(shù)值以64位雙精度浮點(diǎn)數(shù)存儲(chǔ),但位運(yùn)算只能作用于整數(shù),因此要先將 64 位的浮點(diǎn)數(shù)轉(zhuǎn)換成 32 位的整數(shù),然后再進(jìn)行位運(yùn)算,最后再將計(jì)算結(jié)果轉(zhuǎn)換成64位浮點(diǎn)數(shù)存儲(chǔ)。常見(jiàn)的位運(yùn)算有以下幾種:

  • 按位非(NOT):~
  • 按位與(AND):&
  • 按位或(OR): |
  • 按位異或(XOR):^
  • 左移:<<
  • 有符號(hào)右移:>>
  • 無(wú)符號(hào)右移:>>>

需要注意的是:

“有符號(hào)右移” 和 “無(wú)符號(hào)右移” 只在計(jì)算負(fù)數(shù)的情況下存在差異,>> 在符號(hào)位的右側(cè)補(bǔ)0,不移動(dòng)符號(hào)位;而 >>> 是在符號(hào)位的左側(cè)補(bǔ)0,符號(hào)位發(fā)生移動(dòng)和改變。

2.8 四舍五入

JavaScript 對(duì)數(shù)字進(jìn)行四舍五入操作的 API 有 ceil,floor,round,toFixed,toPrecision 等,詳細(xì)介紹請(qǐng)參考:JavaScript 中的四舍五入

3、Boolean 類型

Boolean 類型只有兩個(gè)字面值:true 和 false 。 在 JavaScript 中,所有類型的值都可以轉(zhuǎn)化為與 Boolean 等價(jià)的值 。轉(zhuǎn)化規(guī)則如下:

  • 所有對(duì)象都被當(dāng)作 true
  • 空字符串被當(dāng)作 false
  • null 和 undefined 被當(dāng)作 false
  • 數(shù)字 0 和 NaN 被當(dāng)作 false
Boolean([]); //true
Boolean({}); //true
Boolean(undefined); //false
Boolean(null); //false
Boolean('');  //false
Boolean(0);   //false
Boolean(NaN); //false

除 Boolean() 方法可以返回布爾值外,以下 4 種類型的操作,也會(huì)返回布爾值。

【1】關(guān)系操作符:>,>=,<,<=

當(dāng)關(guān)系操作符的操作數(shù)使用了非數(shù)值時(shí),要進(jìn)行數(shù)據(jù)轉(zhuǎn)換或完成某些奇怪的操作。

  • 如果兩個(gè)操作數(shù)都是數(shù)值,則執(zhí)行數(shù)值比較。
  • 如果兩個(gè)操作數(shù)都是字符串,則逐個(gè)比較兩者對(duì)應(yīng)的字符編碼(charCode),直到分出大小為止 。
  • 如果操作數(shù)是其他基本類型,則調(diào)用Number() 將其轉(zhuǎn)化為數(shù)值,然后進(jìn)行比較。
  • NaN 與任何值比較,均返回 false 。
  • 如果操作數(shù)是對(duì)象,則調(diào)用對(duì)象的 valueOf 方法(如果沒(méi)有 valueOf ,就調(diào)用 toString 方法),最后用得到的結(jié)果,根據(jù)前面的規(guī)則執(zhí)行比較。
'a' > 'b'; // false, 即 'a'.charCodeAt(0) > 'b'.charCodeAt(0)
2 > '1';  // true, 即 Number('1') = 1
true > 0; //true, 即 Number(true) = 1
undefined > 0; //false, Number(undefined) = NaN
null < 0; //false, Number(null) = NaN
new Date > 100; //true , 即 new Date().valueOf()
【2】相等操作符:==,!=,===,!==

== 和 != 操作符都會(huì)先轉(zhuǎn)換操作數(shù),然后再比較它們的相等性。在轉(zhuǎn)換不同的數(shù)據(jù)類型時(shí),需要遵循下列基本規(guī)則:

  • 如果有一個(gè)操作數(shù)是布爾值,則在比較相等性之前,先調(diào)用 Number() 將其轉(zhuǎn)換為數(shù)值;
  • 如果一個(gè)操作數(shù)是字符串,另一個(gè)操作數(shù)是數(shù)值,在比較相等性之前,先調(diào)用 Number() 將字符串轉(zhuǎn)換為數(shù)值;
  • 如果一個(gè)操作數(shù)是對(duì)象,另一個(gè)操作數(shù)不是,則調(diào)用對(duì)象的 valueOf() 方法,用得到的基本類型值按照前面的規(guī)則進(jìn)行比較;
  • null 和 undefined 是相等的。在比較相等性之前,不能將 null 和 undefined 轉(zhuǎn)換成其他任何值。
  • 如果有一個(gè)操作數(shù)是 NaN,則相等操作符返回 false,而不相等操作符返回 true;
  • 如果兩個(gè)操作數(shù)都是對(duì)象,則比較它們的指針地址。如果都指向同一個(gè)對(duì)象,則相等操作符返回 true;否則,返回 false。

=== 和 !== 操作符較大的特點(diǎn)是,在比較之前不轉(zhuǎn)換操作數(shù) 。它們的操作規(guī)則如下:

  • ===: 類型相同,并且值相等,才返回 true ,否則返回 false 。
  • !== : 類型不同,或者值不相等,就返回 true,否則返回 false 。
null === undefined; //false, 類型不同,直接返回 false
[] === []; //false ,類型相同,值不相同,指針地址不同
a=[],b=a,a===b; //true, 類型相同,值也相等
1 !== '1' ; // true , 值相等,但類型不同
[] !== [] ;  // true, 類型相同,但值不相等
【3】布爾操作符:!

布爾操作符屬于一元操作符,即只有一個(gè)分項(xiàng)。其求值過(guò)程如下:

  • 對(duì)分項(xiàng)求值,得到一個(gè)任意類型值;
  • 使用 Boolean() 把該值轉(zhuǎn)換為布爾值 true 或 false;
  • 對(duì)布爾值取反,即 true 變 false,false 變 true
!(2+3) ; // false
!(function(){}); //false
!([] && null && ''); //true

利用 ! 的取反的特點(diǎn),使用 !! 可以很方便的將一個(gè)任意類型值轉(zhuǎn)換為布爾值:

console.log(!!0); //false
console.log(!!''); //false
console.log(!!(2+3)); //true
console.log(!!([] && null && '')); //false

需要注意的是:

邏輯與 “&&” 和 邏輯或 “||” 返回的不一定是布爾值,而是包含布爾值在內(nèi)的任意類型值。

如下所示:

[] && 1; //1
null && undefined; //null
[] || 1; //[]
null || 1; //1

邏輯操作符屬于短路操作符 。在進(jìn)行計(jì)算之前,會(huì)先通過(guò) Boolean() 方法將兩邊的分項(xiàng)轉(zhuǎn)換為布爾值,然后分別遵循下列規(guī)則進(jìn)行計(jì)算:

  • 邏輯與:從左到右檢測(cè)每一個(gè)分項(xiàng),返回第一個(gè)布爾值為 false 的分項(xiàng),并停止檢測(cè) 。如果沒(méi)有檢測(cè)到 false 項(xiàng),則返回最后一個(gè)分項(xiàng) 。
  • 邏輯或:從左到右檢測(cè)每一個(gè)分項(xiàng),返回第一個(gè)布爾值為 true 的分項(xiàng),并停止檢測(cè) 。如果沒(méi)有檢測(cè)到 true 項(xiàng),則返回最后一個(gè)分項(xiàng) 。
[] && {} &&  null && 1; //null
[] && {} &&  !null  &&  1 ; //1
null || undefined || 1 || 0; //1
undefined || 0 || function(){}; //function(){}
【4】條件語(yǔ)句:if,while,?

條件語(yǔ)句通過(guò)計(jì)算表達(dá)式返回一個(gè)布爾值,然后再根據(jù)布爾值的真假,來(lái)執(zhí)行對(duì)應(yīng)的代碼。其計(jì)算過(guò)程如下:

  • 對(duì)表達(dá)式求值,得到一個(gè)任意類型值
  • 使用 Boolean() 將得到的值轉(zhuǎn)換為布爾值 true 或 false
if(arr.length) { }
obj && obj.name ? 'obj.name' : ''
while(arr.length){ }

4、Symbol 類型

Symbol 是 ES6 新增的一種原始數(shù)據(jù)類型,它的字面意思是:符號(hào)、標(biāo)記。代表獨(dú)一無(wú)二的值 。

在 ES6 之前,對(duì)象的屬性名只能是字符串,這樣會(huì)導(dǎo)致一個(gè)問(wèn)題,當(dāng)通過(guò) mixin 模式為對(duì)象注入新屬性的時(shí)候,就可能會(huì)和原來(lái)的屬性名產(chǎn)生沖突 。而在 ES6 中,Symbol 類型也可以作為對(duì)象屬性名,凡是屬性名是 Symbol 類型的,就都是獨(dú)一無(wú)二的,可以保證不會(huì)與其他屬性名產(chǎn)生沖突。

Symbol 值通過(guò)函數(shù)生成,如下所示:

let s = Symbol(); //s是獨(dú)一無(wú)二的值
typeof s ; // symbol  

和其他基本類型不同的是,Symbol 作為基本類型,沒(méi)有對(duì)應(yīng)的包裝類型,也就是說(shuō) Symbol 本身不是對(duì)象,而是一個(gè)函數(shù)。因此,在生成 Symbol 類型值的時(shí)候,不能使用 new 操作符 。

Symbol 函數(shù)可以接受一個(gè)字符串作為參數(shù),表示對(duì) Symbol 值的描述,當(dāng)有多個(gè) Symbol 值時(shí),比較容易區(qū)分。

var s1 = Symbol('s1');
var s2 = Symbol('s2');
console.log(s1,s2); // Symbol(s1) Symbol(s2)

注意,Symbol 函數(shù)的參數(shù)只是表示對(duì)當(dāng)前 Symbol 值的描述,因此,相同參數(shù)的 Symbol 函數(shù)的返回值也是不相等的?!?/p>

用 Symbol 作為對(duì)象的屬性名時(shí),不能直接通過(guò)點(diǎn)的方式訪問(wèn)屬性和設(shè)置屬性值。因?yàn)檎G闆r下,引擎會(huì)把點(diǎn)后面的屬性名解析成字符串。

var s = Symbol();
var obj = {};
obj.s = 'Jack';
console.log(obj); // {s: "Jack"}
obj[s] = 'Jack';
console.log(obj) ; //{Symbol(): "Jack"}

Symbol 作為屬性名,該屬性不會(huì)出現(xiàn)在 for...in、for...of 循環(huán)中,也不會(huì)被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 返回。但是,它也不是私有屬性,有一個(gè) Object.getOwnPropertySymbols() 方法,專門(mén)獲取指定對(duì)象的所有 Symbol 屬性名。

var obj = {};
var s1 = Symbol('s1');
var s2 = Symbol('s2');
obj[s1] = 'Jack';
obj[s2] = 'Tom';
Object.keys(obj); //[]
for(var i in obj){ 
    console.log(i); //無(wú)輸出 
}
Object.getOwnPropertySymbols(obj); //[Symbol(s1), Symbol(s2)]

另一個(gè)新的API,Reflect.ownKeys 方法可以返回所有類型的鍵名,包括常規(guī)鍵名和 Symbol 鍵名。

var obj = {};
var s1 = Symbol('s1');
var s2 = Symbol('s2');
obj[s1] = 'Jack';
obj[s2] = 'Tom';
obj.name = 'Nick';
Reflect.ownKeys(obj); //[Symbol(s1), Symbol(s2),"name"]

有時(shí),我們希望重新使用同一個(gè) Symbol 值,Symbol.for 方法可以做到這一點(diǎn)。它接受一個(gè)字符串作為參數(shù),然后全局搜索有沒(méi)有以該參數(shù)作為名稱的 Symbol 值。如果有,就返回這個(gè) Symbol 值,否則就新建并返回一個(gè)以該字符串為名稱的 Symbol 值。

var s1 = Symbol.for('foo');
var s2 = Symbol.for('foo');
s1 === s2 //true

Symbol.for() 也可以生成 Symbol 值,它 和 Symbol() 的區(qū)別是:

  • Symbol.for() 首先會(huì)在全局環(huán)境中查找給定的 key 是否存在,如果存在就返回,否則就創(chuàng)建一個(gè)以 key 為標(biāo)識(shí)的 Symbol 值
  • Symbol.for() 生成的 Symbol 會(huì)登記在全局環(huán)境中供搜索,而 Symbol() 不會(huì)。

因此,Symbol.for()  永遠(yuǎn)搜索不到 用 Symbol() 產(chǎn)生的值。

var s = Symbol('foo');
var s1 = Symbol.for('foo');
s === s1; // false

Symbol.keyFor() 方法返回一個(gè)已在全局環(huán)境中登記的 Symbol 類型值的 key 。

var s1 = Symbol.for('s1');
Symbol.keyFor(s1); //foo
var s2 = Symbol('s2'); //未登記的 Symbol 值
Symbol.keyFor(s2); //undefined 

5、Undefined 類型

Undefined 是 Javascript 中特殊的原始數(shù)據(jù)類型,它只有一個(gè)值,即 undefined,字面意思是:未定義的值 。它的語(yǔ)義是,希望表示一個(gè)變量最原始的狀態(tài),而非人為操作的結(jié)果 。 這種原始狀態(tài)會(huì)在以下 4 種場(chǎng)景中出現(xiàn):

【1】聲明了一個(gè)變量,但沒(méi)有賦值
var foo;
console.log(foo); //undefined

訪問(wèn) foo,返回了 undefined,表示這個(gè)變量自從聲明了以后,就從來(lái)沒(méi)有使用過(guò),也沒(méi)有定義過(guò)任何有效的值,即處于一種原始而不可用的狀態(tài)。

【2】訪問(wèn)對(duì)象上不存在的屬性
console.log(Object.foo); // undefined
var arr = [];
console.log(arr[0]); // undefined

訪問(wèn) Object 對(duì)象上的 foo 屬性,返回 undefined , 表示Object 上不存在或者沒(méi)有定義名為 foo 的屬性。數(shù)組中的元素在內(nèi)部也屬于對(duì)象屬性,訪問(wèn)下標(biāo)就等于訪問(wèn)這個(gè)屬性,返回 undefined ,就表示數(shù)組中不存在這個(gè)元素。

【3】函數(shù)定義了形參,但沒(méi)有傳遞實(shí)參
// 函數(shù)定義了形參 a
function fn(a) {
    console.log(a); //undefined
}
fn(); // 未傳遞實(shí)參

函數(shù) fn 定義了形參 a, 但 fn 被調(diào)用時(shí)沒(méi)有傳遞參數(shù),因此,fn 運(yùn)行時(shí)的參數(shù) a 就是一個(gè)原始的、未被賦值的變量。

【4】使用 void 對(duì)表達(dá)式求值
void 0 ; // undefined
void false; // undefined
void []; // undefined
void null; // undefined
void function fn(){} ; // undefined

ECMAScript 明確規(guī)定 void 操作符 對(duì)任何表達(dá)式求值都返回 undefined ,這和函數(shù)執(zhí)行操作后沒(méi)有返回值的作用是一樣的,JavaScript 中的函數(shù)都有返回值,當(dāng)沒(méi)有 return 操作時(shí),就默認(rèn)返回一個(gè)原始的狀態(tài)值,這個(gè)值就是 undefined,表明函數(shù)的返回值未被定義。

因此,undefined 一般都來(lái)自于某個(gè)表達(dá)式最原始的狀態(tài)值,不是人為操作的結(jié)果。當(dāng)然,你也可以手動(dòng)給一個(gè)變量賦值 undefined,但這樣做沒(méi)有意義,因?yàn)橐粋€(gè)變量不賦值就是 undefined 。

6、Null 類型

Null 是 Javascript 中特殊的原始數(shù)據(jù)類型,它只有一個(gè)值,即 null,字面意思是:“空值”  。它的語(yǔ)義是,希望表示一個(gè)對(duì)象被人為的重置為空對(duì)象,而非一個(gè)變量最原始的狀態(tài) 。 在內(nèi)存里的表示就是,棧中的變量沒(méi)有指向堆中的內(nèi)存對(duì)象。當(dāng)一個(gè)對(duì)象被賦值了 null 以后,原來(lái)的對(duì)象在內(nèi)存中就處于游離狀態(tài),GC 會(huì)擇機(jī)回收該對(duì)象并釋放內(nèi)存。因此,如果需要釋放某個(gè)對(duì)象,就將變量設(shè)置為 null,即表示該對(duì)象已經(jīng)被清空,目前無(wú)效狀態(tài)。

null 是原始數(shù)據(jù)類型 Null 中的一個(gè)值,但 typeof 會(huì)將 null 誤判為 Object 類型 。

typeof null == 'object'

在 JavaScript 中,數(shù)據(jù)類型在底層都是以二進(jìn)制形式表示的,二進(jìn)制的前三位為 0 會(huì)被 typeof 判定為對(duì)象類型,如下所示:

  • 000 - 對(duì)象,數(shù)據(jù)是對(duì)象的應(yīng)用
  • 1 - 整型,數(shù)據(jù)是31位帶符號(hào)整數(shù)
  • 010 - 雙精度類型,數(shù)據(jù)是雙精度數(shù)字
  • 100 - 字符串,數(shù)據(jù)是字符串
  • 110 - 布爾類型,數(shù)據(jù)是布爾值

而 null 值的二進(jìn)制表示全是 0 ,自然前三位當(dāng)然也是 000,因此,typeof 會(huì)誤以為是對(duì)象類型。如果想要知道 null 的真實(shí)數(shù)據(jù)類型,可以通過(guò)下面的方式來(lái)獲取。

Object.prototype.toString.call(null) ; // [object Null]

7、Object 類型

在 ECMAScript 規(guī)范中,引用類型除 Object 本身外,Date、Array、RegExp 也屬于引用類型 。

引用類型也即對(duì)象類型,ECMA262 把對(duì)象定義為:無(wú)序?qū)傩缘募希鋵傩钥梢园局?、?duì)象或者函數(shù)。 也就是說(shuō),對(duì)象是一組沒(méi)有特定順序的值 。由于其值的大小會(huì)改變,所以不能將其存放在棧中,否則會(huì)降低變量查詢速度。因此,對(duì)象的值存儲(chǔ)在堆(heap)中,而存儲(chǔ)在變量處的值,是一個(gè)指針,指向存儲(chǔ)對(duì)象的內(nèi)存處,即按址訪問(wèn)。具備這種存儲(chǔ)結(jié)構(gòu)的,都可以稱之為引用類型 。

7.1 對(duì)象拷貝

由于引用類型的變量只存指針,而對(duì)象本身存儲(chǔ)在堆中 。因此,當(dāng)把一個(gè)對(duì)象賦值給多個(gè)變量時(shí),就相當(dāng)于把同一個(gè)對(duì)象地址賦值給了每個(gè)變量指針 。這樣,每個(gè)變量都指向了同一個(gè)對(duì)象,當(dāng)通過(guò)一個(gè)變量修改對(duì)象,其他變量也會(huì)同步更新。

var obj = {name:'Jack'};
var obj2 = obj;
obj2.name = 'Tom'
console.log(obj.name,obj2.name); //Tom,Tom

ES6 提供了一個(gè)原生方法用于對(duì)象的拷貝,即 Object.assign() 。

var obj = {name:'Jack'};
var obj2 = Object.assign({},obj);
obj2.name = 'Tom'
console.log(obj.name,obj2.name); //Jack Tom

需要注意的是,Object.assign() 拷貝的是屬性值。當(dāng)屬性值是基本類型時(shí),沒(méi)有什么問(wèn)題 ,但如果該屬性值是一個(gè)指向?qū)ο蟮囊?,它也只能拷貝那個(gè)引用值,而不會(huì)拷貝被引用的那個(gè)對(duì)象。

var obj = {base:{name:'Jack'}};
var obj2 = Object.assign({},obj);
obj2.base.name = 'Tom'
console.log(obj.base.name,obj2.base.name); //Tom Tom  

從結(jié)果可以看出,obj 和 obj2 的屬性 base 指向了同一個(gè)對(duì)象的引用。因此,Object.assign 僅僅是拷貝了一份對(duì)象指針作為副本 。這種拷貝被稱為 “一級(jí)拷貝” 或 “淺拷貝” 。

如果要徹底的拷貝一個(gè)對(duì)象作為副本,兩者之間的操作相互不受影響,則可以通過(guò) JSON 的序列化和反序列化方法來(lái)實(shí)現(xiàn) 。

var obj = {base:{name:'Jack'}};
var obj2 = JSON.parse(JSON.stringify(obj))
obj2.base.name = 'Tom'
console.log(obj.base.name,obj2.base.name); //Jack Tom

這種拷貝被稱為 “多級(jí)拷貝” 或 “深拷貝” 。

7.2 屬性類型

ECMA-262 第 5 版定義了一些內(nèi)部特性(attribute),用以描述對(duì)象屬性(property)的各種特征。ECMA-262 定義這些特性是為了實(shí)現(xiàn) JavaScript 引擎用的,因此在 JavaScript 中不能直接訪問(wèn)它們。為了表示特性是內(nèi)部值,該規(guī)范把它們放在了兩對(duì)兒方括號(hào)中,例如[[Enumerable]]。 這些內(nèi)部特性可以分為兩種:數(shù)據(jù)屬性 和 訪問(wèn)器屬性 。

【1】數(shù)據(jù)屬性

數(shù)據(jù)屬性包含一個(gè)數(shù)據(jù)值的位置,在這個(gè)位置可以讀取和寫(xiě)入值 。數(shù)據(jù)屬性有4個(gè)描述其行為的內(nèi)部特性:

  • [[Configurable]]:能否通過(guò) delete 刪除屬性從而重新定義屬性,或者能否把屬性修改為訪問(wèn)器屬性。該默認(rèn)值為 true。
  • [[Enumerable]]:表示能否通過(guò) for-in 循環(huán)返回屬性。默認(rèn)值為 true。
  • [[Writable]]:能否修改屬性的值。默認(rèn)值為 true。
  • [[Value]]:包含這個(gè)屬性的數(shù)據(jù)值。讀取屬性值的時(shí)候,從這個(gè)位置讀;寫(xiě)入屬性值的時(shí)候,把新值保存在這個(gè)位置。默認(rèn)值為 undefined 。

要修改屬性默認(rèn)的特性,必須使用 ECMAScript 5 的 Object.defineProperty() 方法。這個(gè)方法接收三個(gè)參數(shù):屬性所在的對(duì)象、屬性的名字和一個(gè)描述符對(duì)象。其中,描述符(descriptor)對(duì)象的屬性必須是:configurable、enumerable、writable 和 value。設(shè)置其中的一或多個(gè)值,可以修改對(duì)應(yīng)的特性值。例如:

var person = {};
Object.defineProperty(person, "name", {
    writable: false,
    value: "Nicholas"
});
console.log(person.name); //"Nicholas"
person.name = "Greg";
console.log(person.name); //"Nicholas"

在調(diào)用 Object.defineProperty() 方法時(shí),如果不指定 configurable、enumerable 和 writable 特性,其默認(rèn)值都是 false 。

【2】訪問(wèn)器屬性

訪問(wèn)器屬性不包含數(shù)據(jù)值,它們包含一對(duì) getter 和 setter 函數(shù)(不過(guò),這兩個(gè)函數(shù)都不是必需的)。在讀取訪問(wèn)器屬性時(shí),會(huì)調(diào)用getter 函數(shù),這個(gè)函數(shù)負(fù)責(zé)返回有效的值;在寫(xiě)入訪問(wèn)器屬性時(shí),會(huì)調(diào)用setter 函數(shù)并傳入新值,這個(gè)函數(shù)負(fù)責(zé)決定如何處理數(shù)據(jù)。訪問(wèn)器屬性有如下4 個(gè)特性。

  • [[Configurable]]:表示能否通過(guò) delete 刪除屬性從而重新定義屬性,或者能否把屬性修改為數(shù)據(jù)屬性。默認(rèn)值為true 。
  • [[Enumerable]]:表示能否通過(guò) for-in 循環(huán)返回屬性。默認(rèn)值為 true。
  • [[Get]]:在讀取屬性時(shí)調(diào)用的函數(shù)。默認(rèn)值為 undefined 。
  • [[Set]]:在寫(xiě)入屬性時(shí)調(diào)用的函數(shù)。默認(rèn)值為 undefined 。

訪問(wèn)器屬性不能直接定義,也必須使用 Object.defineProperty() 來(lái)定義。請(qǐng)看下面的例子:

var book = {
    _year: 2004
};
Object.defineProperty(book, "year", {
    get: function () {
        return this._year;
    },
    set: function (newValue) {
        if (newValue > 2004) {
            this._year = newValue;
            console.log('set new value:'+ newValue)
        }
    }
});
book.year = 2005; //set new value:2005
7.3  Object 新增 API

ECMA-262 第 5 版對(duì) Object 對(duì)象進(jìn)行了增強(qiáng),包括 defineProperty 在內(nèi),共定義了 9 個(gè)新的 API:

  • create(prototype[,descriptors]):用于原型鏈繼承。創(chuàng)建一個(gè)對(duì)象,并把其 prototype 屬性賦值為第一個(gè)參數(shù),同時(shí)可以設(shè)置多個(gè) descriptors 。
  • defineProperty(O,Prop,descriptor) :用于定義對(duì)象屬性的特性。
  • defineProperties(O,descriptors) :用于同時(shí)定義多個(gè)屬性的特性。
  • getOwnPropertyDescriptor(O,property):獲取 defineProperty 方法設(shè)置的 property 特性。
  • getOwnPropertyNames:獲取所有的屬性名,不包括 prototy 中的屬性,返回一個(gè)數(shù)組。
  • keys():和 getOwnPropertyNames 方法類似,但是獲取所有的可枚舉的屬性,返回一個(gè)數(shù)組。
  • preventExtensions(O) :用于鎖住對(duì)象屬性,使其不能夠拓展,也就是不能增加新的屬性,但是屬性的值仍然可以更改,也可以把屬性刪除。
  • Object.seal(O) :把對(duì)象密封,也就是讓對(duì)象既不可以拓展也不可以刪除屬性(把每個(gè)屬性的 configurable 設(shè)為 false),單數(shù)屬性值仍然可以修改。
  • Object.freeze(O) :完全凍結(jié)對(duì)象,在 seal 的基礎(chǔ)上,屬性值也不可以修改(每個(gè)屬性的 wirtable 也被設(shè)為 false)。

感謝各位的閱讀!關(guān)于javascript中有哪些數(shù)據(jù)類型就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

文章名稱:javascript中有哪些數(shù)據(jù)類型-創(chuàng)新互聯(lián)
網(wǎng)頁(yè)網(wǎng)址:http://muchs.cn/article14/coesge.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、軟件開(kāi)發(fā)網(wǎng)站設(shè)計(jì)、服務(wù)器托管標(biāo)簽優(yōu)化、微信公眾號(hào)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開(kāi)發(fā)公司