前言
前方高能預(yù)警:本文中Number類型
及其基礎(chǔ)誉尖、硬核且無(wú)聊狭郑,導(dǎo)致大部分人覺(jué)得這些內(nèi)容沒(méi)什么用腹暖。如果你中途堅(jiān)持不住,建議點(diǎn)贊翰萨,收藏后脏答,改日再戰(zhàn)。
對(duì)于初次接觸JavaScript的朋友來(lái)說(shuō)缨历,本文信息量略為豐富以蕴,建議收藏糙麦,多多復(fù)習(xí)辛孵,練習(xí)。
如果你為了追求極致的學(xué)習(xí)速度赡磅,想知道JavaScript與C++/Java不同之處魄缚,請(qǐng)直接翻到文末小結(jié)部分。
數(shù)據(jù)類型
ECMAScript中有5種基本數(shù)據(jù)類型:Undefined
, Null
, Boolean
, Number
和String
和一種復(fù)雜數(shù)據(jù)類型Object
。
ECMAScript不支持任何創(chuàng)建自定義類型的機(jī)制冶匹,所有值最終都將是上述6種數(shù)據(jù)類型之一习劫。
typeof操作符
對(duì)一個(gè)值使用typeof
操作符,可能會(huì)返回下列某個(gè)字符串:
-
"undefined"
嚼隘,變量未被初始化诽里,或變量未被定義。 -
"boolean"
飞蛹,布爾值谤狡。 -
"string"
,字符串卧檐。 -
"number"
墓懂,數(shù)值。 -
"object"
霉囚,對(duì)象或null
捕仔。 -
"function"
,函數(shù)盈罐。
Undefined類型
Undefined類型
只有一個(gè)值榜跌,就是undefined
。
在使用var
聲明變量但未對(duì)其進(jìn)行初始化時(shí)盅粪,該值為undefined
斜做。
包含undefined
值的變量和尚未定義的變量是不一樣的,如下例:
var message; //該變量默認(rèn)為undefined湾揽。
//下面變量未被聲明
//var age;
alert(message); //undefined
alert(age); //ReferenceError: age is not defined.
迷惑的是瓤逼,在使用typeof
操作符時(shí),兩者的值都是undefined
库物,如下例:
alert(typeof message); //"undefined"
alert(typeof age); //"undefined"
所以霸旗,強(qiáng)烈推薦顯式的初始化變量。這樣戚揭,我們就可以知道被檢測(cè)的變量的狀態(tài)是沒(méi)聲明诱告,而不是尚未初始化。**
Null類型
Null類型也只有一個(gè)值民晒,就是null
精居。
從邏輯角度來(lái)看,null
值表示一個(gè)對(duì)象的空指針潜必,事實(shí)上靴姿,這也就解釋了為什么在使用typeof
操作符檢測(cè)null
時(shí),會(huì)返回"object"磁滚。如下例所示佛吓。
var car = null;
alert(typeof car); //"object"
如果定義的變量要用于保存對(duì)象的話宵晚,最好將該變量初始化為null
。這樣只需要檢查null
值就可以知道相應(yīng)的變量是否已經(jīng)保存了一個(gè)變量引用维雇。
var car = null;
if( car!=null ){
//對(duì)car對(duì)象執(zhí)行某些操作
}
需要注意的是淤刃,undefined
的值是派生自null
值的,因此ECMA-262規(guī)定對(duì)它們進(jìn)行相等性測(cè)試時(shí)吱型,必須返回true逸贾。
alert( undefined==null ); //true
無(wú)論在什么情況下都沒(méi)必要把一個(gè)變量的值顯式設(shè)置為undefined,這樣可以有助于區(qū)分undefined
與null
津滞。
Boolean類型
Boolean
類型是ECMAScript中使用最多的一種類型耕陷,該類型只有兩個(gè)字面值true
和false
。(注意:true
和false
是區(qū)分大小寫的)
ECMAScript中所有類型的值都可以通過(guò)Boolean()
函數(shù)來(lái)轉(zhuǎn)換為相應(yīng)的等價(jià)值据沈。
var message = "Hello World!";
alert(Boolean(message)); //true
下表為各類數(shù)據(jù)類型與Boolean
類型的轉(zhuǎn)換規(guī)則哟沫。
數(shù)據(jù)類型 | 轉(zhuǎn)換為ture | 轉(zhuǎn)換為false |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | "" |
Number | 任何非零數(shù)字值(包括無(wú)窮大) | 0和NaN |
Object | 任何對(duì)象 | null |
Undefined | 無(wú) | undefined |
Number類型
最基本的字面值格式是十進(jìn)制整數(shù),如下:
var intNum = 123;
除十進(jìn)制外锌介,整數(shù)還可以通過(guò)八進(jìn)制或十六進(jìn)制的字面值來(lái)表示嗜诀。
八進(jìn)制
八進(jìn)制字面值的第一位必須是零(0),然后是八進(jìn)制數(shù)字序列(0~7)孔祸。如果字面值中的數(shù)值超出了范圍隆敢,那么前導(dǎo)0將會(huì)被忽略,后面的數(shù)值按照十進(jìn)制解析崔慧。如下例:
var octalNum1 = 070; //八進(jìn)制的56
var octalNum2 = 079; //無(wú)效的八進(jìn)制數(shù)值拂蝎,解析為79
var octalNum3 = 08; //無(wú)效的八進(jìn)制數(shù)據(jù),解析為8
八進(jìn)制在嚴(yán)格模式下是無(wú)效的惶室,會(huì)導(dǎo)致支持的JavaScript引擎拋出錯(cuò)誤温自。
十六進(jìn)制
十六進(jìn)制的前兩位必須是0x,后跟任何十六進(jìn)制數(shù)字(0~9及A~F)皇钞。其中悼泌,A~F字母即可以大寫,也可以小寫夹界。
var hexNum1 = 0xA; //十六進(jìn)制的10
var hexNum2 = 0x1f; //十六進(jìn)制的31
在進(jìn)行算數(shù)運(yùn)算時(shí)馆里,所有以八進(jìn)制和十六進(jìn)制表示的數(shù)值最終都將轉(zhuǎn)換為十進(jìn)制數(shù)值。
浮點(diǎn)數(shù)值
浮點(diǎn)數(shù)值可柿,該數(shù)值中必須包含一個(gè)小數(shù)點(diǎn)鸠踪,并且小數(shù)點(diǎn)后面至少得有一位數(shù)字。
小數(shù)點(diǎn)前面可以省略整數(shù)复斥,但不推薦营密。
var floatNum1 = 1.1;
var floatNum2 = 0.1;
var floatNum3 = .1; //有效,但不推薦永票。
由于保存浮點(diǎn)整數(shù)需要的內(nèi)存空間是保存整數(shù)的兩倍卵贱,所以ECMAScript會(huì)不失時(shí)機(jī)的將浮點(diǎn)數(shù)值轉(zhuǎn)換為整數(shù)值滥沫。
var floatNum1 = 1.; //小數(shù)點(diǎn)后面沒(méi)有數(shù)字侣集,解析為1键俱。
var floatNum2 = 10.0; //整數(shù),解析為10世分。
對(duì)于極大或極小的值编振,可以使用e表示法(科學(xué)計(jì)數(shù)法)表示的浮點(diǎn)數(shù)表示。
var floatNum1 = 3.125e7; //3.125*10^7 = 31250000
var floatNum2 = 3e-17; //3*10^(-17) = 0.00000000000000003
浮點(diǎn)數(shù)值的最高精度是17位小數(shù)臭埋,但在算術(shù)計(jì)算時(shí)踪央,其精度遠(yuǎn)遠(yuǎn)不如整數(shù)。
alert(0.1+0.2); //0.30000000000000004
alert(0.1+0.2==0.3); //false
數(shù)值范圍
ECMAScript能夠表示最小的數(shù)值保存在Number.MIN_VALUE
瓢阴,大多數(shù)瀏覽器中畅蹂,其值為5e-324
。
ECMAScript能夠表示最大的數(shù)值保存在Number.MAX_VALUE
中荣恐,大多數(shù)瀏覽器中液斜,其值為1.7976931348623157e+308
。
當(dāng)某次計(jì)算的結(jié)果得到了超出JavaScript數(shù)值范圍的值時(shí)叠穆,這個(gè)數(shù)值會(huì)自動(dòng)轉(zhuǎn)換為Infinity
值少漆。
當(dāng)該值為正無(wú)窮時(shí),得到的是Infinity
值硼被;該值為負(fù)無(wú)窮時(shí)示损,得到的是-Infinity
值。
當(dāng)某次計(jì)算的值返回了正或負(fù)Infinity
值時(shí)嚷硫,該值無(wú)法繼續(xù)參與下一次計(jì)算检访,因?yàn)?code>Infinity不是能夠參與計(jì)算的數(shù)值。
我們可以通過(guò)isFinite()
函數(shù)來(lái)判斷一個(gè)數(shù)值是否是無(wú)窮仔掸。
alert(isFinite(0)); //false
alert(isFinite(Number.MAX_VALUE+1)); //true
NaN
NaN
烛谊,非數(shù)值,是一個(gè)特殊的數(shù)值嘉汰,用于表示一個(gè)本來(lái)要返回?cái)?shù)值的操作未返回?cái)?shù)值的情況丹禀。例如:
alert(1/0); //NaN
NaN
本身有兩個(gè)非比尋常的特點(diǎn)。
-
任何涉及與
NaN
操作鞋怀,結(jié)果都是NaN
双泪。(好比0乘任何數(shù)都得0) NaN
不與任何數(shù)值相等,包括NaN
自己密似。
alert(0*NaN); //NaN
alert(0/NaN); //NaN
alert(0+NaN); //NaN
alert(0-NaN); //NaN
alert(NaN==NaN); //false
因此焙矛,ECMAScript定義了isNaN()
函數(shù),用來(lái)確定參數(shù)是否為NaN
残腌。
該函數(shù)接受到值后村斟,會(huì)嘗試將該值轉(zhuǎn)換為數(shù)值贫导,任何不能被轉(zhuǎn)換為數(shù)值的值都會(huì)導(dǎo)致這個(gè)函數(shù)返回true。
alert(isNaN(NaN)); //true
alert(isNaN(0)); //false
alert(isNaN("Hello")); //true, "Hello"不能被轉(zhuǎn)換為數(shù)值蟆盹。
alert(isNaN(isNaN(NaN))) //false
數(shù)值轉(zhuǎn)換
有三個(gè)函數(shù)孩灯,可以把非數(shù)值轉(zhuǎn)換為數(shù)值。
-
Number()
逾滥,將任何數(shù)據(jù)類型轉(zhuǎn)換為整型數(shù)值峰档。 -
parseInt()
,將字符串轉(zhuǎn)為整型數(shù)值寨昙。 -
parseFloat()
, 將字符串轉(zhuǎn)為浮點(diǎn)型數(shù)值讥巡。
Number()
轉(zhuǎn)換規(guī)則如下:
-
Boolean
類型,true
和false
被轉(zhuǎn)換為1
和0
舔哪。 - 數(shù)字類型欢顷,只是簡(jiǎn)單的傳入和返回。
-
null
捉蚤,返回0
抬驴。 -
undefined
,返回NaN
外里。 - 字符串遵循以下規(guī)則:
- 如果字符串中只包含數(shù)字怎爵,則將其轉(zhuǎn)換為十進(jìn)制數(shù)。
- 如果字符串中包含有效的浮點(diǎn)數(shù)格式盅蝗,則轉(zhuǎn)換為相應(yīng)的浮點(diǎn)數(shù)值鳖链。
- 如果字符串中包含有效的16進(jìn)制格式,則轉(zhuǎn)換為相同大小的10進(jìn)制數(shù)值墩莫。
- 如果字符串為
""
芙委,返回0。 - 如果字符串中包含上述格式之外的字符狂秦,則轉(zhuǎn)換為
NaN
灌侣。
- 如果是對(duì)象,則調(diào)用對(duì)象的
valueOf()
方法裂问,然后依照前面的規(guī)則轉(zhuǎn)換返回的值侧啼。如果轉(zhuǎn)換的結(jié)果是NaN,則調(diào)用對(duì)象的toString()
方法堪簿,然后再依照前面的規(guī)則轉(zhuǎn)換返回的字符痊乾。
var num1 = Number("1111"); //1111
var num2 = Number(true); //1
var num3 = Number(""); //0
var num4 = Number("123a"); //NaN,因?yàn)榘帜竌
var num5 = Number("0xf"); //15
相比較Number()
函數(shù)椭更,parseInt()
函轉(zhuǎn)換規(guī)則就寬松多了哪审,parseInt()
函數(shù)在轉(zhuǎn)換字符串時(shí),更多的是看其是否符合數(shù)值模式虑瀑。
它會(huì)忽略字符串前面的空格湿滓,直至找到第一個(gè)非空格字符滴须。
如果第一個(gè)字符不是負(fù)號(hào)或數(shù)字,那么parseInt()
函數(shù)會(huì)返回NaN
叽奥。
如果第一個(gè)字符是數(shù)字扔水,parseInt()
函數(shù)會(huì)繼續(xù)解析第二個(gè)字符,直到解析完成而线,或者遇到非數(shù)字字符铭污。
如果字符串以0x
開(kāi)頭恋日,parseInt()
函數(shù)會(huì)將其當(dāng)作16進(jìn)制整數(shù)膀篮。
var num1 = parseInt(" 123"); //123
var num2 = parseInt("123a"); //123
var num3 = parseInt(""); //NaN
var num4 = parseInt("0xf"); //15
var num5 = parseInt("07"); //ECMAScript3中返回56,ECMAScript5以上返回7
在使用parseInt()
函數(shù)解析八進(jìn)制字面值數(shù)值時(shí)岂膳,ECMAScript3和ECMAScript5存在分歧誓竿,為了消除上述困惑,可以為這個(gè)函數(shù)提供第二個(gè)參數(shù):轉(zhuǎn)換時(shí)的基數(shù)谈截。
如果知道當(dāng)前字符串是16進(jìn)制筷屡,那么可以指定基數(shù)為16,例子如下:
var num1 = parseInt("f",16); //15
var num2 = parseInt("70",8); //56
var num3 = parseInt("10",2); //2
不指定基數(shù)意味著讓parseInt()
函數(shù)決定如何解析輸入的字符串簸喂,為了避免錯(cuò)誤解析毙死,強(qiáng)烈建議無(wú)論在什么情況下都明確指定基數(shù)。
parseFloat()
函數(shù)與parseInt()
函數(shù)類似喻鳄,也是從第一個(gè)字符開(kāi)始解析每一個(gè)字符扼倘,而且也是一直解析到字符串末尾,或者解析遇到了一個(gè)無(wú)效的浮點(diǎn)數(shù)字符為止除呵。
parseFloat()
函數(shù)會(huì)始終忽略前導(dǎo)的0
再菊。由于parseFloat()
函數(shù)只解析10進(jìn)制數(shù),因此它沒(méi)有第二個(gè)參數(shù)指定基數(shù)的用法颜曾。
如果字符串包含的是一個(gè)可解析為整數(shù)的數(shù)纠拔,parseFloat()
函數(shù)會(huì)返回整數(shù)。
var num1 = parseFloat("1234abcd"); //1234泛豪,解析到整數(shù)值稠诲,返回整數(shù)1234
var num2 = parseFloat("0xA"); //0,遇到x無(wú)效字符诡曙,返回0
var num3 = parseFloat("22.5"); //22.5
var num4 = parseFloat("22.34.5"); //22.34臀叙,遇到.無(wú)效字符,返回22.34
var num5 = parseFloat("0908.5"); //908.5岗仑,忽略前導(dǎo)0匹耕,返回908.5
var num6 = parseFloat("3.125e7"); //31250000
String類型
String
類型用于表示零或多個(gè)16位Unicode
組成的字符序列,即字符串荠雕。
通常有兩種表示方法稳其。(ECMAScript6中驶赏,新增一種表示方法)
var firstName = "Nicholas";
var lastName = 'Zakas';
單引號(hào)表示的字符串與雙引號(hào)表示的字符串完全相同,但雙引號(hào)開(kāi)頭必須雙引號(hào)結(jié)尾既鞠,單引號(hào)開(kāi)頭必須單引號(hào)結(jié)尾煤傍。
字面值常量
String
類型包含一些特殊的字符字面值,也叫轉(zhuǎn)義序列嘱蛋,用于表示非打印字符蚯姆,或其它用途的字符,這些字面值如下表所示:
字面量 | 含義 |
---|---|
\n | 換行 |
\t | 制表 |
\b | 空格 |
\r | 回車 |
\f | 進(jìn)紙 |
\\ | 斜杠 |
\' | 單引號(hào)' |
\" | 雙引號(hào)" |
\xnn | 以16進(jìn)制代碼nn表示字符洒敏,\x41表示"A" |
\unnnn | 以十六進(jìn)制代碼nnnn表示一個(gè)Unicode字符龄恋,\u03a3表示希臘字母 |
上述字符字面值可以出現(xiàn)在字符串中任意位置,而且也作為一個(gè)字符被解析凶伙。
var text = "This is the letter sigma: \u03a3.";
alert(text.length); //28
如果字符串中包含雙字節(jié)字符郭毕,那么length
屬性可能不會(huì)精確返回字符串中字符的數(shù)目。
字符串的特點(diǎn)
ECMAScript中的字符串是不可變的函荣,也就是說(shuō)显押,字符串一旦創(chuàng)建,他們的值就不能改變傻挂。
要改變某個(gè)變量保存的字符串乘碑,首先得先銷毀原來(lái)的字符串,再用另一個(gè)新字符串填充該變量金拒。
var str = "Hello";
str = str + " World!"; // Hello World!
轉(zhuǎn)換為字符串
有兩種方式可以將一個(gè)值轉(zhuǎn)換為字符串:
除了null
和undefined
之外兽肤,每個(gè)值都有的toString()
函數(shù)。
var x = 100;
var xString = x.toString(); // "100"
var y = true;
var yString = y.toString(); // "true"
大多數(shù)情況下殖蚕,toString()
函數(shù)不必傳遞參數(shù)轿衔,但在調(diào)用數(shù)值的toString()
函數(shù)時(shí),可以傳遞一個(gè)參數(shù):輸出值的基數(shù)睦疫。
var num = 10;
var numString1 = num.toString(); // "10"
var numString2 = num.toString(2); // "1010"
var numString3 = num.toString(8); // "12"
var numString4 = num.toString(10); // "10"
var numString5 = num.toString(16); // "a"
在不知道值是否為null
或undefined
時(shí)害驹,還可以使用轉(zhuǎn)型函數(shù)String()
,這個(gè)函數(shù)能夠?qū)⑷魏晤愋偷闹缔D(zhuǎn)換為字符串蛤育。
String()
函數(shù)遵循下列轉(zhuǎn)換規(guī)則:
- 如果值有
toString()
函數(shù)宛官,則調(diào)用該方法,并返回相應(yīng)的結(jié)果瓦糕。 - 如果值是
null
底洗,則返回"null"
。 - 如果值是
undefined
咕娄,則返回"undefined"
亥揖。
var v1 = 123;
var v2 = true;
var v3 = null;
var v4;
alert(String(v1)); // "123"
alert(String(v2)); // "true"
alert(String(v3)); // ”null“
alert(String(v4)); // "undefined"
Object類型
ECMAScript中的對(duì)象其實(shí)就是一組數(shù)據(jù)和功能的集合。對(duì)象可以通過(guò)執(zhí)行new
操作符后跟要?jiǎng)?chuàng)建的對(duì)象名稱來(lái)創(chuàng)建。
var o = new Object();
這個(gè)語(yǔ)法與Java中創(chuàng)建對(duì)象的語(yǔ)法相似费变,但在ECMAScript中摧扇,如果不給構(gòu)造函數(shù)傳遞參數(shù),則可以省略后面的那對(duì)圓括號(hào)挚歧。(不推薦此做法)
在ECMAScript中扛稽,Object
類型是所有它的實(shí)例的基礎(chǔ),換句話說(shuō)滑负,Object
類型所具有的任何屬性和方法也同樣存在更具體的對(duì)象中在张。
Object
的每個(gè)實(shí)例都有下列屬性和方法。
-
Constructor
矮慕,保存著用于創(chuàng)建當(dāng)前對(duì)象的函數(shù)帮匾。 -
hasOwnProperty(propertyName)
,用于檢查給定的屬性在當(dāng)前實(shí)例中是否存在凡傅,其中propertyName
參數(shù)必須以字符串形式指定辟狈。 -
isPrototypeOf(object)
肠缔,用于檢查傳入的對(duì)象是否是另一個(gè)對(duì)象的原型夏跷。 -
propertyIsEnumerable(propertyName)
,用于檢查給定的屬性是否能使用for-in
語(yǔ)句來(lái)枚舉明未。 -
toLocaleString()
槽华,返回對(duì)象的字符串表示,該字符串與執(zhí)行環(huán)境地區(qū)相對(duì)應(yīng)趟妥。 -
toString()
猫态,返回對(duì)象的字符串表示。 -
valueOf()
披摄,返回對(duì)象的字符串亲雪,數(shù)值或布爾值表示。通常與toString()
方法的返回值相同疚膊。
從技術(shù)角度來(lái)說(shuō)义辕,ECMA-262中對(duì)象的行為不一定適用于JavaScript中的其他對(duì)象。瀏覽器中的對(duì)象寓盗,比如BOM和DOM中的對(duì)象灌砖,都屬于宿主對(duì)象企蹭,因?yàn)樗鼈兪怯伤拗鲗?shí)現(xiàn)提供和定義的帖烘。
總結(jié)
本文總結(jié)分為如下三大部分亿卤,以下總結(jié)不知道原理的撰豺,評(píng)論區(qū)見(jiàn)代兵。
與C++/Java不同之處
- JavaScript只有6種數(shù)據(jù)類型(
Number
,Boolean
,Object
,Undefined
,Null
,String
)笛园,且不支持用戶自定義類型兜挨。 - JavaScript中當(dāng)計(jì)算溢出時(shí)退唠,結(jié)果會(huì)為正或負(fù)
Infinity
箩艺。 - JavaScript中有一個(gè)神奇的值
NaN
窜醉。
嚴(yán)格模式
- 在嚴(yán)格模式下制跟,不能定義以八進(jìn)制為字面值表示整數(shù),會(huì)導(dǎo)致引擎拋出錯(cuò)誤酱虎。
Effective小技巧
- 強(qiáng)烈建議雨膨,定義變量時(shí),顯式的將其初始化读串。(為什么聊记?)
- 強(qiáng)烈建議,任何情況下恢暖,定義變量時(shí)排监,都不要將其初始化為
undefined
。(為什么杰捂?) - 強(qiáng)烈建議舆床,定義要保存對(duì)象的變量時(shí),將其初始化為
null
嫁佳。(為什么挨队?) - 強(qiáng)烈建議,使用
parseInt()
函數(shù)蒿往,而不是Number()
函數(shù)盛垦。 - 強(qiáng)烈建議,使用
parseInt()
函數(shù)時(shí)瓤漏,明確指定基數(shù)腾夯。