JavaScript基礎(一)之數值轉換
- 有3個函數可以把非數值轉換爲數值:
Number()
;parseInt()
;parseFloat()
;
Number()
函數,即轉型函數,可以用於任何數據類型,而另外兩個函數則專門用於把字符串轉換成數值。Number()
函數的轉型規則如下:-
如果是
Boolean
值,true
和false
將分別被轉換爲1
和0
; -
如果是數字值,只是簡單的傳入和返回;
-
如果是
null
值,返回0
; -
如果是
undefined
, 返回NaN
; -
如果是字符串,遵循下列規則:
- 如果是字符串中包含數字(包括前面帶正號或者負號的情況),則將其轉換爲十進制數值,即"1"會變成
1
,"123"
會變成123
, 而"011"
會變成11
(注意: 前導的零被忽略了); - 如果字符串中包含有效的浮點格式,如
"1.1"
, 則將其轉換爲對應的浮點數值(同樣,也會忽略前導零); - 如果字符串中包含有效的十六進制格式,例如
"0xf"
, 則將其轉換爲相同大小的十進制整數值;
如果是八進制數與二進制數,那麼Number()函數處理會是怎麼樣的?
- 如果是字符串中包含有效的八進制格式,如
"070"
,在八進制數 - 如果字符串是空的(不包含任何字符),則將其轉換爲
0
; - 如果字符串中包含除上述格式之外的字符,則將其轉換爲
NaN
;
- 如果是字符串中包含數字(包括前面帶正號或者負號的情況),則將其轉換爲十進制數值,即"1"會變成
-
如果是對象,則調用對象的
valueOf()
方法,然後依照前面的規則將轉換返回的值。如果轉換的結果是NaN
, 則調用對象的toString()
方法,然後再次依照前面的規則轉換返回的字符串值。
-
- 根據這麼多的規則使用
Number()
把各種數據類型轉換爲數值確實有點複雜。下面還是給出幾個具體的例子:
var num1 = Number("Hello world!"); // NaN
var num2 = Number(" "); // 0
var num3 = Number("00000000012"); // 12
var num4 = Number(true); // 1
var num5 = Number(false); // 0
var num6 = Number(0.1); // 0.1
var num7 = Number(1); // 1
var num8 = NUmber(3.14156); // 3.14156
var num9 = Number(null); // 0
var num10 = Number(undefined); // NaN
var num11 = Number("0.1"); // 0.1
var num12 = Number("1"); // 1
var num13 = Number("3.14156"); // 3.1416
var num14 = Number("00.1"); // 0.1
var num15 = Number("0xf"); // 15
var num16 = Number("0xe"); // 14
var num17 = Number("0xg"); // NaN
- 後話:一元操作符的操作與
Number()
函數相同。 - 由於
Number()
函數在轉換字符串時比較複雜而且不夠合理,因此在處理整數的時候更常用的是parseInt()
函數。 parseInt()
函數在轉換字符串時,更多的是看其是否符合數值模式。它會忽略字符串前面的空格,直至找到第一個非空格字符。- 如果第一個字符不是數字字符或者負號,
parseInt()
就會返回NaN
;也就是說,用parseInt()
轉換空字符串會返回NaN
(Number()
函數對空字符串返回0)。 - 如果第一個字符串是數字,
parseInt()
會繼續解析第二個字符,直到解析完所有後續字符或者遇到了一個非數字字符。例如,"1234blue"
會被轉換爲1234
,因爲"blue"
會被完全忽略。類似地,"22.5"
會被轉換爲22
, 因爲小數點並不是有效的數字字符。 - 如果字符串中的第一個字符是數字字符,
parseInt()
也能夠識別出各種整數格式(即十進制、八進制和十六進制數)。也就是說,如果字符串以"0x"
開頭且後跟數字字符,就會將其當作一個十六進制整數;如果字符串以"0"
開頭且後跟數字字符,則會將其當作一個八進制整數來解析。 - 爲了更好地理解
parseInt()
函數的轉換規則,下面給出了例子:
var num1 = parseInt("1234blue"); // 1234
var num2 = parseInt(" "); // NaN
var num3 = parseInt("0xA"); // 10(十六進制整數)
var num4 = parseInt(22.5); // 22
var num5 = parseInt("070"); // 56(八進制整數)
var num6 = parseInt("70"); // 70(十進制整數)
var num7 = parseInt("0xf"); // 15(十六進制整數)
- 在使用
parseInt()
解析想八進制字面量的字符串時,ECMAScript 3和5存在分歧。例如:
// ECMAScript 3認爲是56(八進制整數),ECMAScript 5認爲是0(十進制整數)
var num = parseInt("070");
- 在ECMAScript 5中, 即使是在嚴格模式下也會如此。
- 爲了消除在使用
parseInt()
函數時可能導致的上述困惑,可以爲這個函數提供第二個參數;轉換時使用的基數(即多少進制)。如果知道要解析的值是是十六進制格式的字符串,那麼指定基數16
作爲第二個參數,可以保證得到正確的結果,例如:
var num = parseInt("0xAF", 16); // 175
- 實際上,如果指定了
16
作爲第二個參數,字符串可以不帶前面的"0x"
, 如下所示:
var num1 = parseInt("AF", 16); // 175
var num2 = parseInt("AF"); // NaN
- 第一個轉換傳入了基數,明確告訴
parseInt()
要解析一個十六進制格式的字符串; 而第二個轉換髮現第一個字符不是數字字符, 因此就自動終止。 - 指定基數會影響到轉換的輸出結果。例如:
var num1 = parseInt("10", 2); //2 (按二進制解析)
var num2 = parseInt("10", 8); //8 (按八進制解析)
var num3 = parseInt("10", 10); //10 (按十進制解析)
var num4 = parseInt("10", 16); //16 (按十六進制解析)
- 不指定基數意味着
parseInt()
決定如何解析輸入的字符串,因此爲了避免錯誤的解析,我們建議無論在什麼情況下都明確指定基數。 - 題外話:
- 在多數情況下,要解析的都是十進制數值,因此始終將10作爲第二個參數是非常必要的。
- 與
parseInt()
的函數類似,parseFloat()
也是從第一個字符(位置0)開始解析每個字符。而且也是一直解析到字符串末尾,或者解析到遇見第一個無效的浮點數爲止。也就是說,字符串中的第一個小數點是有效的,而第二個小數點是無效的了。因此它後面的字符串將被忽略。舉例來說: “22.34.5"將會被轉換爲"22.34”。 - 除了第一個小數點有效外,
parseInt()
和parseFloat
的第二個區別在於它始終都會忽略前導的零。 parseFloat()
可以識別前面討論過的所有浮點數數值格式,也包括十進制整數格式。但十六進制格式的字符串則始終會被轉換成0。- 由於
parseFloat()
只解析十進制值,因此它沒有用第二個參數指定基數的用法。 - 最後還是要注意一點: 如果字符串包含的是一個可解析爲整數的值(沒有小數點,或者小數點後都是零),
parseFloat()
會返回整數。
var num1 = parseFloat("123blue"); // 1234(整數)
var num2 = parseFloat("0xA"); // 0
var num3 = parseFloat("22.5"); // 22.5
var num4 = parseFloat("22.34.5"); // 22.34
var num5 = parseFloat("0908.5"); // 908.5
var num6 = parseFloat("3.125e7"); // 31250000
String
類型:
String
類型用於表示零或者多個16位Unicode
字符組成的字符序列,即字符串。字符串可以用雙引號(")或者單引號(’)表示,因此下面兩種字符的寫法都是有效的:
var firstName = "Nicholas";
var lastName = "Zakas";
- 與PHP中的雙引號和單引號會影響對字符串的解釋方式不同,ECMAScript中的這兩種語法形式沒有什麼區別。用雙引號表示的字符串和用單引號表示的字符串完全相同。不過, 以雙引號開頭的字符串也必須是以雙引號結尾,而以單引號開頭的字符串必須是以單引號結尾。
var firstName = 'Nicholas"; // 語法錯誤(左右引號必須匹配)
- 字符字面量
String
數據類型包好一些特殊的字符字面量,也叫轉義序列,用於表示非打印字符,或者具有其他用途的字符。這些字符字面量如下表示:
字面量 | 含義 |
---|---|
\n | 換行 |
\t | 製表 |
\b | 空格 |
\r | 回車 |
\f | 換頁符 |
\ | 斜槓 |
’ | 單引號(’),早使用單引號表示的字符串中使用。例如: ‘He said, ‘hey.’’ |
" | 雙引號("),早使用雙引號表示的字符串中使用。例如: “He said, “hey.”” |
\xnn | 以十六進制代碼nn表示的一個字符(其中n爲0~F)。例如, \x41表示"A" |
\unnnn | 以十六進制代碼nnnn表示的一個Unicode字符(其中n爲0~F)。例如, \u03a3表示希臘字符 |
- 這些字符字面量可以出現在字符串中的任意位置,而且也將被作爲一個字符串來解析,如下面的例子所示:
var text = "This is the letter sigma: \u03a3.";
- 這個例子中的變量
test
有28個字符,其中6個字符長的轉義序列表示一個字符。 - 任何字符串的長度都可以通過訪問其
length
屬性取得,例如:
alert(text.length); //輸出28
- 這個屬性返回的字符數包括
16
個字符的數目。如果字符串中包含雙字節字符,那麼length
屬性可能不會精確地返回字符串中的字符數目。 - 字符串的特點:
ECMAScript
中的字符串是不可變的,也就是說,字符串一旦創建,它們的值就不能改變。要改變某個變量保存的字符串,首先要銷燬原來的字符串,然後再另一個包含新值的字符串填充該變量。例如:
var lang = "Java"
lang = lang + "Script"
- 以上示例中的變量
lang
開始時包含字符串"Java"。而第而行代碼把lang
的值重新定義爲"Java"與"Script"的組合,即"JavaScript"。實現這個操作的過程如下: 首先創建一個能容納10個字符的新字符串,然後在這個字符串中填充"Java"和"Script",最後一步是銷燬原來的字符串"Java"和字符串"Script",因爲這兩個字符串已經沒用了。這個過程是在後臺發生的,而這也是在某些舊版本的瀏覽器(例如版本低於1.0的Firefox, IE6等)中拼接字符串時速度很慢的原因所在。但這些瀏覽器後來的版本已經解決了這個版本低效率問題。 - 轉換爲字符串:
- 要把一個值轉換爲一個字符串有兩種方式。第一種是使用幾乎每個值都有的
toString()
方法。這個方法唯一要做的就是返回相應值的字符串表現。來看下面的例子:
var age = 11;
var ageAsString = age.toString(); // 字符串"11"
var found = true;
var foundAsString = found.toSring(); // 字符串"true"
- 數值、布爾值、對象和字符串值(沒錯,每個字符串也都有一個
toString()
方法,該方法返回字符串的一個副本)都有toString()
方法。但null
和undefined
值都沒有這個方法。 - 多數情況下,調用
toString()
方法不必傳遞參數。但是在調用數值的toString
方法時,可以傳遞一個參數: 輸出數值的基數。默認情況下,toString()
方法以十進制格式返回數值的字符串表示。而通過傳遞基數,toString()
可以輸出以二進制、八進制、十六進制,乃至其他任意有效進制格式表示的字符串值,下面給出幾個例子:
var num = 10;
console.log(num.toString()); // "10"
console.log(num.toString(2)); // "1010"
console.log(num.toString(8)); // "12"
console.log(num.toString(10)); // "10"
console.log(num.toString(16)); // "a"
- 通過指定基數,
toString()
方法會改變輸出的值。而數值10
根據基數的不同, 可以在輸出時被轉換爲不同的數值格式。默認的(沒有參數的)輸出值與指定基數10
時的輸出值相同。 - 在不知道要轉換的值是不是
null
或者undefined
的情況下,還可以使用轉型函數String()
,這個函數能夠將任何類型的值轉換爲字符串。String()
函數遵循下列轉換規則:- 如果有值
toString()
方法,則調用該方法(沒有參數)並返回相應的結果; - 如果是值
null
, 則返回"null"
; - 如果值是
undefined
,則返回"undefined"
。
- 如果有值
- 例子:
var value1 = 10;
var value2 = true;
var value3 = null;
var value4;
console.log(String(value1)); // "10"
console.log(String(value2)); // "true"
console.log(String(value3)); // "null"
console.log(String(value4)); // "undefined"
- 數值、布爾值、
null
和undefined
。數值和布爾值的轉換結果與調用toString()
方法得到的結果相同。因爲null
和undefined
沒有toString()
方法,所以String()函數就返回了這兩個值的字面量。
JackDan Thinking