
JavaScript中總共有6種數(shù)據(jù)類型。可分為兩大類:簡(jiǎn)單數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型。
說明一下:上面這句話現(xiàn)在來說應(yīng)該是不對(duì)的,因?yàn)镋S6中新增了數(shù)據(jù)類型。不過我們暫時(shí)不涉及ES6。
簡(jiǎn)單數(shù)據(jù)類型即基本數(shù)據(jù)類型,共有5種:Undefined、Null、Boolean、Number、String,其值分別對(duì)應(yīng)undefined、null、布爾值true和false、數(shù)值、字符串值。
復(fù)雜數(shù)據(jù)類型只有一種,就是Object——對(duì)象。JS中的對(duì)象就是一組無(wú)序鍵值對(duì)外面套一個(gè)大括號(hào){}所構(gòu)成。Object非常常用、非常強(qiáng)大、非常有意思,而且對(duì)于JS這門語(yǔ)言結(jié)構(gòu)來說,Object意義不一般。這些,之后的文章再來討論吧。
ECMAScript不支持任何創(chuàng)建自定義類型的機(jī)制,而所有值最終都將是上述6種數(shù)據(jù)類型之一。
上面這句話引用自《JavaScript高級(jí)程序設(shè)計(jì)(第3版)》(之后簡(jiǎn)稱J3),其實(shí)不用多解釋,這句話說的很明白了。這就是說,你“定義”的所有變量,它的類型都是唯一確定的,必定是上述6種之一。
這里的“定義”兩個(gè)字,我加了引號(hào),是想表示這個(gè)詞廣義上的意思。在一般的編程語(yǔ)言中,當(dāng)你想“定義”一個(gè)變量時(shí),不外乎3種情況:聲明,定義,初始化。聲明就如字面意思一樣,僅僅是宣稱一個(gè)命名;定義就是給這個(gè)命名分配內(nèi)存空間;初始化則是給這個(gè)內(nèi)存空間賦值。顯然,他們3個(gè)是循序漸進(jìn)的。在JS中,我們所說的初始化其實(shí)做的事是分配內(nèi)存并賦值,也就是定義并初始化。所以在JS中,我們一般只說聲明和初始化??慈缦麓a:
var value1; //聲明變量
value1 = 'Hello'; //(定義并)初始化
var value2 = 'Hello'; //聲明并初始化
再摘錄博客園的一句話,對(duì)于聲明、定義與初始化大家應(yīng)該就能完全理解了:
因?yàn)閖avascript為動(dòng)態(tài)語(yǔ)言,其變量并沒有固定的類型,其存儲(chǔ)空間大小會(huì)隨初始化與賦值而變化,所以其變量的“定義”就不像傳統(tǒng)的靜態(tài)語(yǔ)言一樣了,其定義顯得無(wú)關(guān)緊要。
http://www.cnblogs.com/silentjesse/p/4024536.html
接下來,讓我們來具體看一看JavaScript的6種數(shù)據(jù)類型。
不過首先,必須先了解一個(gè)操作符—typeof。顧名思義,這個(gè)操作符的作用就是返回某個(gè)變量的數(shù)據(jù)類型。對(duì)某個(gè)值使用typeof操作符始終會(huì)返回以下6個(gè)字符串之一:'undefined'、'boolean'、'number'、'string'、'object'、'function'。你肯定發(fā)現(xiàn)了一個(gè)問題,就是這6個(gè)字符串為什么不和6種數(shù)據(jù)類型完全對(duì)應(yīng)?沒有'null'嗎?'function'又是哪兒來的?請(qǐng)看下面的測(cè)試代碼:
console.log(typeof null) //'object'
var f = function(){};
console.log(typeof f); //'function'
注意到,對(duì)Null類型的唯一值null使用typeof操作符返回的不是什么'null',而是'object',這是為什么呢?這是因?yàn)?code>null這個(gè)值比較特殊,它是基本數(shù)據(jù)類型Null的唯一值,但同時(shí),它又被認(rèn)為是一個(gè)空的對(duì)象(Object)引用。
有些時(shí)候,typeof 操作符會(huì)返回一些令人迷惑但技術(shù)上卻正確的值。比如,調(diào)用typeof null會(huì)返回"object",因?yàn)樘厥庵祅ull 被認(rèn)為是一個(gè)空的對(duì)象引用?!禞3》
對(duì)于typeof可以返回'function',這么理解吧:
從技術(shù)角度講,函數(shù)在ECMAScript 中是對(duì)象,不是一種數(shù)據(jù)類型。然而,函數(shù)也確實(shí)有一些特殊的屬性,因此通過typeof 操作符來區(qū)分函數(shù)和其他對(duì)象是有必要的?!禞3》
在JS中,Function和Object的關(guān)系很微妙也很復(fù)雜,需要對(duì)原型構(gòu)造、原型鏈等一些知識(shí)有所理解之后才能進(jìn)一步理解這兩者的關(guān)系。不過這并不影響我們現(xiàn)在的理解,站在數(shù)據(jù)類型的角度,我們可以明確地認(rèn)為Function就是一類特殊的Object。至于對(duì)一個(gè)Function使用typeof操作符的返回結(jié)果是'function'而不是'object',原因就像書上說的,只是因?yàn)槲覀冇斜匾浪且粋€(gè)函數(shù)而不是一般的對(duì)象。
介紹完typeof操作符這個(gè)實(shí)用的工具,下面就真的具體來看看JS的6種數(shù)據(jù)類型吧。
Undefined 類型
- 只有一個(gè)唯一值,即
undefined。 - 所有只進(jìn)行了聲明而未初始化的變量,其值都是
undefined。比如:
var a;
console.log(a); //undefined(注意,這可不是字符串)
需要明白的是,undefined是一個(gè)明確的、合法的值,而不是一個(gè)錯(cuò)誤。真正會(huì)導(dǎo)致錯(cuò)誤的是如下的代碼:
console.log(b); //Uncaught ReferenceError: b is not defined
這行代碼會(huì)報(bào)一個(gè)空引用異常的錯(cuò)誤,因?yàn)樽兞縝沒有聲明。這很好理解。
- 還有一點(diǎn)需要了解,對(duì)于上邊兩段示例代碼中的變量 a 和 b,執(zhí)行
typeof操作都會(huì)返回'undefined':
var a;
console.log(typeof a); //'undefined'
console.log(typeof b); //'undefined'
看起來,你可能會(huì)覺得對(duì) b 執(zhí)行typeof應(yīng)該報(bào)錯(cuò)才對(duì),但因?yàn)?code>typeof必然會(huì)返回6個(gè)字符串之一,所以并不會(huì)報(bào)錯(cuò)。而且,無(wú)論是 a 還是 b,都無(wú)法執(zhí)行真正的操作,那么就讓 b 和 a 一樣返回'undefined'好了。看一下書上的解釋:
結(jié)果表明,對(duì)未初始化和未聲明的變量執(zhí)行typeof 操作符都返回了undefined 值;這個(gè)結(jié)果有其邏輯上的合理性。因?yàn)殡m然這兩種變量從技術(shù)角度看有本質(zhì)區(qū)別,但實(shí)際上無(wú)論對(duì)哪種變量也不可能執(zhí)行真正的操作?!禞3》
由此可知,當(dāng)你使用typeof操作符檢測(cè)變量的數(shù)據(jù)類型時(shí),如果返回的是'undefined',那么這個(gè)變量可能是未初始化,也可能是未聲明。因此,從規(guī)范性上來說,為了避免這種模糊,我們?cè)诙x變量時(shí)最好直接進(jìn)行初始化。這樣的話,如果還返回'undefined',那么我們立即就能知道是因?yàn)檫@個(gè)變量壓根就沒聲明了。
Null 類型
- 只有一個(gè)唯一值,即
null。 -
null表示一個(gè)空對(duì)象(Object)引用,因此typeof null會(huì)返回'object'。 - 實(shí)際上,
undefined派生自null,因此undefined == null返回true,但是undefined === null會(huì)返回false,因?yàn)檫@兩個(gè)值的數(shù)據(jù)類型不一樣。這里補(bǔ)充一下:==是相等操作符,===是全等操作符,前者會(huì)對(duì)操作數(shù)自動(dòng)進(jìn)行轉(zhuǎn)型,而后者不會(huì),后者只有在兩個(gè)操作數(shù)未經(jīng)轉(zhuǎn)換就相等的情況下才返回true。 - 還有一點(diǎn),如果某個(gè)變量用來在以后保存對(duì)象,那么最好將其初始化為
null,以方便區(qū)分和判斷。
Boolean 類型
- 布爾類型,有2個(gè)值:
true和false。 - 其他所有數(shù)據(jù)類型都有與
true和false對(duì)應(yīng)的值,通過轉(zhuǎn)型函數(shù)Boolean()可以得到某個(gè)值所對(duì)應(yīng)的布爾值。如:
var s = 'Hello';
console.log(Boolean(s)); //true
轉(zhuǎn)換規(guī)則如下表:

在流程控制語(yǔ)句中,比如在
if語(yǔ)句的小括號(hào)內(nèi),會(huì)自動(dòng)對(duì)操作數(shù)調(diào)用轉(zhuǎn)型函數(shù)Boolean()再求最終的布爾值。如下:
var s = 'Hello';
if(s){
//do something //后臺(tái)自動(dòng)對(duì)s調(diào)用轉(zhuǎn)型函數(shù)`Boolean()`,因?yàn)閟不是空串,會(huì)返回true
}
Number 類型
數(shù)值類型。了解幾個(gè)知識(shí)點(diǎn)即可。
- 保存浮點(diǎn)數(shù)所需的內(nèi)存空間是整數(shù)值的2倍;
- 永遠(yuǎn)不要測(cè)試特定的浮點(diǎn)數(shù)值,如:
var a = 0.1;
var b = 0.2;
console.log(a + b); //0.30000000000000004 有誤差,并不會(huì)是0.3
-
NaN是一個(gè)特殊的Number值,它的存在是為了避免程序直接報(bào)錯(cuò),比如0/0的結(jié)果就是NaN;NaN的任何操作都會(huì)返回NaN;NaN與任何值都不相等,包括它本身:NaN === NaN會(huì)返回false; - 另外,還有
parseInt()和parseFloat()等常用轉(zhuǎn)型函數(shù)的用法自行Google即可。
String 類型
字符串類型。在這里了解幾個(gè)點(diǎn)即可,之后在引用類型等處會(huì)做詳細(xì)介紹。
單引號(hào)
''和雙引號(hào)""都可以使用且沒有任何差別。ECMAScript 中的字符串是不可變的,也就是說,字符串一旦創(chuàng)建,它們的值就不能改變。要改變某個(gè)變量保存的字符串,首先要銷毀原來的字符串,然后再用另一個(gè)包含新值的字符串填充該變量。——《J3》
將某個(gè)值轉(zhuǎn)換為字符串,可以使用以下3種方法:
toString()方法、轉(zhuǎn)型函數(shù)String()、加空串+ ''。
Object 類型
對(duì)象類型。Object是所有對(duì)象的基礎(chǔ),其所具有的屬性和方法其他對(duì)象也必然擁有。這里只列幾個(gè)Object的屬性和方法:
-
constructor:保存著用于創(chuàng)建當(dāng)前對(duì)象的構(gòu)造函數(shù); -
hasOwnProperty('屬性名'):用于檢查給定的屬性在當(dāng)前對(duì)象實(shí)例中是否存在(不查找原型鏈); -
isPrototypeOf(某一Object類型):用于檢查對(duì)象實(shí)例是否是傳入對(duì)象的原型; -
propertyIsEnumerable('屬性名'):用于檢查傳入的屬性是否可以枚舉; -
toString():返回該對(duì)象的字符串表示; -
toLocalString():同上,與所在地區(qū)有關(guān) -
valueOf():返回對(duì)象最有意義的那個(gè)值,返回的可能是字符串、數(shù)值或者布爾值。