1.簡介
JavaScript 語言的每一個值,都屬於某一種數據類型。JavaScript 的數據類型,共有六種。(ES6 新增了第七種 Symbol 類型的值。)
- 數值(number):整數和小數(比如
1
和3.14
) - 字符串(string):文本(比如
Hello World
)。 - 布爾值(boolean):表示真僞的兩個特殊值,即
true
(真)和false
(假) undefined
:表示“未定義”或不存在,即由於目前沒有定義,所以此處暫時沒有任何值null
:表示空值,即此處的值爲空。- 對象(object):各種值組成的集合。
通常,數值、字符串、布爾值這三種類型,合稱爲原始類型(primitive type)的值,即它們是最基本的數據類型,不能再細分了。對象則稱爲合成類型(complex type)的值,因爲一個對象往往是多個原始類型的值的合成,可以看作是一個存放各種值的容器。至於undefined
和null
,一般將它們看成兩個特殊值。
對象是最複雜的數據類型,又可以分成三個子類型。
- 狹義的對象(object)
- 數組(array)
- 函數(function)
狹義的對象和數組是兩種不同的數據組合方式,函數其實是處理數據的方法,可以賦值給變量,這爲編程帶來了很大的靈活性,也爲 JavaScript 的“函數式編程”奠定了基礎。
2.typeof 運算符
JavaScript 有三種方法,可以確定一個值到底是什麼類型。
typeof
運算符instanceof
運算符Object.prototype.toString
方法
typeof
運算符可以返回一個值的數據類型。
數值、字符串、布爾值分別返回number
、string
、boolean
,函數返回function
。
typeof 123 // "number"
typeof '123' // "string"
typeof false // "boolean"
function f() {}
typeof f // "function"
undefined
返回undefined
。
typeof undefined // "undefined"
利用這一點,typeof可以用來檢查一個沒有聲明的變量,而不報錯。實際編程中,這個特點通常用在判斷語句。
// 錯誤的寫法
if (v) {
// ...
}
// ReferenceError: v is not defined
// 正確的寫法
if (typeof v === "undefined") {
// ...
}
對象返回object
。
typeof window // "object"
typeof {} // "object"
typeof [] // "object",數組本質上只是一種特殊的對象。instanceof運算符可以區分數組和對象。
var o = {};
var a = [];
o instanceof Array // false
a instanceof Array // true
null
返回object
。
typeof null // "object"
null
的類型是object
,這是由於歷史原因造成的。1995年的 JavaScript 語言第一版,只設計了五種數據類型(對象、整數、浮點數、字符串和布爾值),沒考慮null
,只把它當作object
的一種特殊值。後來null
獨立出來,作爲一種單獨的數據類型,爲了兼容以前的代碼,typeof null
返回object
就沒法改變了。
3.null 和 undefined
3.1 概述
null
與undefined
都可以表示“沒有”,含義非常相似。將一個變量賦值爲undefined
或null
,語法效果幾乎沒區別。在if
語句中,它們都會被自動轉爲false
,相等運算符(==
)甚至直接報告兩者相等。
var a = undefined;
// 或者
var a = null;
if (!undefined) {
console.log('undefined is false'); // undefined is false
}
if (!null) {
console.log('null is false'); // null is false
}
undefined == null // true
null
和undefined
的區別:看這裏。
3.2 用法和含義
對於null
和undefined
,大致可以像下面這樣理解。
null
表示空值,即該處的值現在爲空。調用函數時,某個參數未設置任何值,這時就可以傳入null
,表示該參數爲空。比如,某個函數接受引擎拋出的錯誤作爲參數,如果運行過程中未出錯,那麼這個參數就會傳入null
,表示未發生錯誤。
undefined
表示“未定義”,下面是返回undefined
的典型場景。
// 變量聲明瞭,但沒有賦值
var i;
i // undefined
// 調用函數時,應該提供的參數沒有提供,該參數等於 undefined
function f(x) {
return x;
}
f() // undefined
// 對象沒有賦值的屬性
var o = new Object();
o.p // undefined
// 函數沒有返回值時,默認返回 undefined
function f() {}
f() // undefined
4.布爾值
布爾值代表“真”和“假”兩個狀態。“真”用關鍵字true
表示,“假”用關鍵字false
表示。布爾值只有這兩個值。
下列運算符會返回布爾值:
- 前置邏輯運算符:
!
(Not) - 相等運算符:
===
,!==
,==
,!=
- 比較運算符:
>
,>=
,<
,<=
如果 JavaScript 預期某個位置應該是布爾值,會將該位置上現有的值自動轉爲布爾值。轉換規則是除了下面六個值被轉爲false
,其他值都視爲true
。
undefined
null
false
0
NaN
""
或''
(空字符串)
注意,空數組([]
)和空對象({}
)對應的布爾值,都是true
。
5.數值
5.1 概述
5.1.1 整數和浮點數
JavaScript 內部,所有數字都是以64位浮點數形式儲存,即使整數也是如此。所以,1
與1.0
是相同的,是同一個數。
1 === 1.0 // true
這就是說,JavaScript 語言的底層根本沒有整數,所有數字都是小數(64位浮點數)。容易造成混淆的是,某些運算只有整數才能完成,此時 JavaScript 會自動把64位浮點數,轉成32位整數,然後再進行運算。
由於浮點數不是精確的值,所以涉及小數的比較和運算要特別小心。
0.1 + 0.2 === 0.3
// false
0.1 * 100 + 0.2 * 100 === 0.3 * 100
// true
0.3 / 0.1
// 2.9999999999999996
(0.3 - 0.2) === (0.2 - 0.1)
// false
5.1.2 數值精度
根據國際標準 IEEE 754,JavaScript 浮點數的64個二進制位,從最左邊開始,是這樣組成的。
- 第1位:符號位,0表示正數,1表示負數
- 第2位到第12位(共11位):指數部分
- 第13位到第64位(共52位):小數部分(即有效數字)
符號位決定了一個數的正負,指數部分決定了數值的大小,小數部分決定了數值的精度。有效數字這時總是1.xx...xx
的形式,其中xx…xx的部分保存在64位浮點數之中,最長可能爲52位。因此,JavaScript 提供的有效數字最長爲53個二進制位。
(-1)^符號位 * 1.xx...xx * 2^指數部分
精度最多隻能到53個二進制位,這意味着,絕對值小於2的53次方的整數,即-253到253,都可以精確表示。
Math.pow(2, 53)
// 9007199254740992
Math.pow(2, 53) + 1
// 9007199254740992
Math.pow(2, 53) + 2
// 9007199254740994
Math.pow(2, 53) + 3
// 9007199254740996
Math.pow(2, 53) + 4
// 9007199254740996
上面代碼中,大於2的53次方以後,整數運算的結果開始出現錯誤。
5.1.3 數值範圍
根據標準,64位浮點數的指數部分的長度是11個二進制位,意味着指數部分的最大值是2047(2的11次方減1)。也就是說,64位浮點數的指數部分的值最大爲2047,分出一半表示負數,則 JavaScript 能夠表示的數值範圍爲21024到2-1023(開區間),超出這個範圍的數無法表示。
如果一個數大於等於2的1024次方,那麼就會發生“正向溢出”,即 JavaScript 無法表示這麼大的數,這時就會返回Infinity
。
Math.pow(2, 1024) // Infinity
如果一個數小於等於2的-1075次方(指數部分最小值-1023,再加上小數部分的52位),那麼就會發生爲“負向溢出”,即 JavaScript 無法表示這麼小的數,這時會直接返回0。
Math.pow(2, -1075) // 0
JavaScript 提供Number
對象的MAX_VALUE
和MIN_VALUE
屬性,返回可以表示的具體的最大值和最小值。
Number.MAX_VALUE // 1.7976931348623157e+308
Number.MIN_VALUE // 5e-324
5.2數值的表示法
JavaScript 的數值有多種表示方法,可以用字面形式直接表示,比如35
(十進制)和0xFF
(十六進制)。
數值也可以採用科學計數法表示,下面是幾個科學計數法的例子。
123e3 // 123000
123e-3 // 0.123
-3.1E+12
.1e-23
科學計數法允許字母e
或E
的後面,跟着一個整數,表示這個數值的指數部分。
以下兩種情況,JavaScript 會自動將數值轉爲科學計數法表示,其他情況都採用字面形式直接表示。
(1)小數點前的數字多於21位。
1234567890123456789012
// 1.2345678901234568e+21
123456789012345678901
// 123456789012345680000
(2)小數點後的零多於5個。
// 小數點後緊跟5個以上的零,
// 就自動轉爲科學計數法
0.0000003 // 3e-7
// 否則,就保持原來的字面形式
0.000003 // 0.000003
5.3數值的進制
使用字面量(literal)直接表示一個數值時,JavaScript 對整數提供四種進制的表示方法:十進制
、十六進制
、八進制
、二進制
。
- 十進制:沒有前導0的數值。
- 八進制:有前綴0o或0O的數值,或者有前導0、且只用到0-7的八個阿拉伯數字的數值。
- 十六進制:有前綴0x或0X的數值。
- 二進制:有前綴0b或0B的數值。
默認情況下,JavaScript 內部會自動將八進制(0-8)
、十六進制(0-9,a-f)
、二進制(0-1)
轉爲十進制。下面是一些例子。
0xff // 255 15*16 + 15
0o377 // 255 3*8*8 + 7*8 + 7
0b11 // 3 2*1 + 1
如果八進制、十六進制、二進制的數值裏面,出現不屬於該進制的數字,就會報錯。
0xzz // 報錯
0o88 // 報錯
0b22 // 報錯
通常來說,有前導0的數值會被視爲八進制,但是如果前導0後面有數字8和9,則該數值被視爲十進制。
0888 // 888
0777 // 511
前導0表示八進制,處理時很容易造成混亂。ES5 的嚴格模式和 ES6,已經廢除了這種表示法,但是瀏覽器爲了兼容以前的代碼,目前還繼續支持這種表示法。
5.4特殊數值
5.4.1 正零和負零
前面說過,JavaScript 的64位浮點數之中,有一個二進制位是符號位。這意味着,任何一個數都有一個對應的負值,就連0
也不例外。
JavaScript 內部實際上存在2個0:一個是+0
,一個是-0
,區別就是64位浮點數表示法的符號位不同。它們是等價的。
-0 === +0 // true
0 === -0 // true
0 === +0 // true
幾乎所有場合,正零和負零都會被當作正常的0
。
+0 // 0
-0 // 0
(-0).toString() // '0'
(+0).toString() // '0'
唯一有區別的場合是,+0
或-0
當作分母,返回的值是不相等的。
1 / +0 //+Infinity
1 / -0 //-Infinity
// 所以
(1 / +0) === (1 / -0) // false
5.4.2 NaN
(1)含義
NaN
是 JavaScript 的特殊值,表示“非數字”(Not a Number),主要出現在將字符串解析成數字出錯的場合。
5 - 'x' // NaN
上面代碼運行時,會自動將字符串x轉爲數值,但是由於x不是數值,所以最後得到結果爲NaN,表示它是“非數字”(NaN
)。
Math.acos(2) // NaN
Math.log(-1) // NaN
Math.sqrt(-1) // NaN
0 / 0 // NaN
需要注意的是,NaN
不是獨立的數據類型,而是一個特殊數值,它的數據類型依然屬於Number
,使用typeof
運算符可以看得很清楚。
typeof NaN // 'number'
(2)運算規則
NaN不等於任何值,包括它本身。
NaN === NaN // false
數組的indexOf
方法內部使用的是嚴格相等運算符,所以該方法對NaN
不成立。
[NaN].indexOf(NaN) // -1
NaN
在布爾運算時被當作false
。
Boolean(NaN) // false
NaN
與任何數(包括它自己)的運算,得到的都是NaN
。
NaN + 32 // NaN
NaN - 32 // NaN
NaN * 32 // NaN
NaN / 32 // NaN
5.4.3 Infinity
(1)含義
Infinity
表示“無窮”,用來表示兩種場景。一種是一個正的數值太大,或一個負的數值太小,無法表示;另一種是非0數值除以0,得到Infinity。
// 場景一,表達式的計算結果太大
Math.pow(2, 1024)
// Infinity
// 場景二
0 / 0 // NaN
1 / 0 // Infinity
Infinity
有正負之分,Infinity
表示正的無窮,-Infinity
表示負的無窮。
Infinity === -Infinity // false
1 / -0 // -Infinity,非零正數除以-0
-1 / -0 // Infinity,負數除以-0
Infinity
大於一切數值(除了NaN
),-Infinity
小於一切數值(除了NaN
)。
Infinity > 1000 // true
-Infinity < -1000 // true
Infinity
與NaN
比較,總是返回false
。
Infinity > NaN // false
-Infinity > NaN // false
Infinity < NaN // false
-Infinity < NaN // false
(2)運算規則
Infinity的四則運算,符合無窮的數學計算規則。
5 * Infinity // Infinity
5 - Infinity // -Infinity
Infinity / 5 // Infinity
5 / Infinity // 0
0 * Infinity // NaN
0 / Infinity // 0
Infinity / 0 // Infinity
Infinity + Infinity // Infinity
Infinity * Infinity // Infinity
Infinity - Infinity // NaN
Infinity / Infinity // NaN
Infinity
與null
計算時,null
會轉成0
,等同於與0
的計算。
// null會轉成0,等同於與0的計算
null * Infinity // NaN
null / Infinity // 0
Infinity / null // Infinity
Infinity
與undefined
計算,返回的都是NaN
。
5.5與數值相關的全局方法
5.5.1 parseInt()
(1)基本用法
parseInt方法用於將字符串轉爲整數。
parseInt('123') // 123
parseInt(' 81') // 81,字符串頭部有空格,空格會被自動去除
// parseInt的參數不是字符串,則會先轉爲字符串再轉換
parseInt(1.23) // 1
// 等同於
parseInt('1.23') // 1
字符串轉爲整數的時候,是一個個字符依次轉換,如果遇到不能轉爲數字的字符,就不再進行下去,返回已經轉好的部分。
parseInt('8a') // 8
parseInt('12**') // 12
parseInt('12.34') // 12
parseInt('15e2') // 15
parseInt('15px') // 15
如果字符串的第一個字符不能轉化爲數字(後面跟着數字的正負號除外),返回NaN
。
parseInt('abc') // NaN
parseInt('.3') // NaN
parseInt('') // NaN
parseInt('+') // NaN
parseInt('+1') // 1
所以,parseInt
的返回值只有兩種可能,要麼是一個十進制整數,要麼是NaN
。
如果字符串以0x
或0X
開頭,parseInt
會將其按照十六進制數解析。
parseInt('0x10') // 16
如果字符串以0
開頭,將其按照10進制解析。
parseInt('011') // 11
(2)進制轉換
parseInt
方法還可以接受第二個參數(2到36之間),表示被解析的值的進制,返回該值對應的十進制數。默認情況下,parseInt
的第二個參數爲10,即默認是十進制轉十進制。
注意:第二個參數之前不懂,刷題時曾出現錯誤
parseInt('1000') // 1000
// 等同於
parseInt('1000', 10) // 1000
下面是轉換指定進制的數的例子。
parseInt('1000', 2) // 8,2^3 + 0 + 0 + 0
parseInt('1000', 6) // 216,6^3 + 0 + 0 + 0
parseInt('1000', 8) // 512,8^3 + 0 + 0 + 0
如果第二個參數不是數值,會被自動轉爲一個整數。這個整數只有在2到36之間,才能得到有意義的結果,超出這個範圍,則返回NaN。如果第二個參數是0
、undefined
和null
,則直接忽略。
parseInt('10', 37) // NaN,不在2~36之間
parseInt('10', 1) // NaN
parseInt('10', 0) // 10
parseInt('10', null) // 10
parseInt('10', undefined) // 10
如果字符串包含對於指定進制無意義的字符,則從最高位開始,只返回可以轉換的數值。如果最高位無法轉換,則直接返回NaN
。
parseInt('1546', 2) // 1,5 4 6均無意義,返回 1*2^0
parseInt('546', 2) // NaN
前面說過,如果parseInt的第一個參數不是字符串,會被先轉爲字符串。這會導致一些令人意外的結果。
parseInt(0x11, 36) // 43,
parseInt(0x11, 2) // 1
// 等同於
parseInt(String(0x11), 36)
parseInt(String(0x11), 2)
// 等同於
parseInt('17', 36)
parseInt('17', 2) // 7無意義
這種處理方式,對於八進制的前綴0,尤其需要注意。
parseInt(011, 2) // NaN
// 等同於
parseInt(String(011), 2)
// 等同於
parseInt(String(9), 2)
parseInt('011', 2) // 3,1*2^1 + 1*2^0 = 3,'011'爲字符串,不用轉換
JavaScript 不再允許將帶有前綴0的數字視爲八進制數,而是要求忽略這個0。但是,爲了保證兼容性,大部分瀏覽器並沒有部署這一條規定。
5.5.2 parseFloat()
parseFloat
方法用於將一個字符串轉爲浮點數。
parseFloat('3.14') // 3.14
如果字符串符合科學計數法,則會進行相應的轉換。
parseFloat('314e-2') // 3.14
parseFloat('0.0314E+2') // 3.14
如果字符串包含不能轉爲浮點數的字符,則不再進行往後轉換,返回已經轉好的部分。
parseFloat('3.14more non-digit characters') // 3.14
parseFloat方法會自動過濾字符串前導的空格。
parseFloat('\t\v\r12.34\n ') // 12.34
如果parseFloat參數不是字符串,或者字符串的第一個字符不能轉化爲浮點數,則返回NaN。
parseFloat([]) // NaN
parseFloat('FF2') // NaN
parseFloat('') // NaN
上面代碼中,尤其值得注意,parseFloat
會將空字符串轉爲NaN
。
這些特點使得parseFloat的轉換結果不同於Number
函數。
parseFloat(true) // NaN
Number(true) // 1
parseFloat(null) // NaN
Number(null) // 0
parseFloat('') // NaN
Number('') // 0
parseFloat('123.45#') // 123.45
Number('123.45#') // NaN
5.5.3 isNaN()
注意注意注意,之前忘記了isNaN方法。
isNaN
方法可以用來判斷一個值是否爲NaN
。
isNaN(NaN) // true
isNaN(123) // false
但是,isNaN只對數值有效,如果傳入其他值,會被先轉成數值。比如,傳入字符串的時候,字符串會被先轉成NaN
,所以最後返回true
,這一點要特別引起注意。也就是說,isNaN
爲true
的值,有可能不是NaN
,而是一個字符串。
isNaN('Hello') // true
// 相當於
isNaN(Number('Hello')) // true
出於同樣的原因,對於對象和數組,isNaN
也返回true
。
isNaN({}) // true
// 等同於
isNaN(Number({})) // true
isNaN(['xzy']) // true
// 等同於
isNaN(Number(['xzy'])) // true
但是,對於空數組和只有一個數值成員的數組,isNaN
返回false
。
isNaN([]) // false
isNaN([123]) // false
isNaN(['123']) // false
// 原因
Number([123] // 123
Number(['123'] // 123
因此,使用isNaN之前,最好判斷一下數據類型。
function myIsNaN(value) {
return typeof value === 'number' && isNaN(value);
}
判斷NaN
更可靠的方法是,利用NaN爲唯一不等於自身的值
的這個特點,進行判斷。
function myIsNaN(value) {
return value !== value;
}
5.5.4 isFinite()
isFinite
方法返回一個布爾值,表示某個值是否爲正常的數值。
isFinite(Infinity) // false
isFinite(-Infinity) // false
isFinite(NaN) // false
isFinite(undefined) // false
// 除了上述四個,isFinite對於其他的數值都會返回true
isFinite(null) // true
isFinite(-1) // true
6.字符串
6.1 定義
字符串就是零個或多個排在一起的字符,放在單引號或雙引號之中。
'abc'
"abc"
單引號字符串的內部,可以使用雙引號。雙引號字符串的內部,可以使用單引號。eg:
'key = "value"'
"It's a long journey"
如果要在單引號字符串的內部,使用單引號,就必須在內部的單引號前面加上反斜槓,用來轉義。雙引號字符串內部使用雙引號,也是如此。
'Did she say \'Hello\'?'
// "Did she say 'Hello'?"
"Did she say \"Hello\"?"
// "Did she say "Hello"?"
字符串默認只能寫在一行內,分成多行將會報錯。
'a
b
c'
// SyntaxError: Unexpected token ILLEGAL
如果長字符串必須分成多行,可以在每一行的尾部使用反斜槓。
var longString = 'Long \
long \
long \
string';
longString
// "Long long long string"
上面代碼表示,加了反斜槓以後,原來寫在一行的字符串,可以分成多行書寫。但是,輸出的時候還是單行,效果與寫在同一行完全一樣。注意,反斜槓的後面必須是換行符,而不能有其他字符(比如空格),否則會報錯。
連接運算符(+
)可以連接多個單行字符串,將長字符串拆成多行書寫,輸出的時候也是單行。
var longString = 'Long '
+ 'long '
+ 'long '
+ 'string';
6.2 轉義
反斜槓(\)在字符串內有特殊含義,用來表示一些特殊字符,所以又稱爲轉義符。
需要用反斜槓轉義的特殊字符,主要有下面這些。
\0
:null(\u0000
)\b
:後退鍵(\u0008
)\f
:換頁符(\u000C
)\n
:換行符(\u000A
)\r
:回車鍵(\u000D
)\t
:製表符(\u0009
)\v
:垂直製表符(\u000B
)\'
:單引號(\u0027
)\"
:雙引號(\u0022
)\\
:反斜槓(\u005C
)
上面這些字符前面加上反斜槓,都表示特殊含義。
console.log('1\n2')
// 1
// 2
上面代碼中,\n
表示換行,輸出的時候就分成了兩行。
反斜槓還有三種特殊用法。
(1)\HHH
反斜槓後面緊跟三個八進制數(000
到377
),代表一個字符。HHH
對應該字符的 Unicode 碼點,比如\251
表示版權符號。顯然,這種方法只能輸出256種字符。
(2)\xHH
\x
後面緊跟兩個十六進制數(00
到FF
),代表一個字符。HH
對應該字符的 Unicode 碼點,比如\xA9
表示版權符號。這種方法也只能輸出256種字符。
(3)\uXXXX
\u
後面緊跟四個十六進制數(0000
到FFFF
),代表一個字符。XXXX
對應該字符的 Unicode 碼點,比如\u00A9
表示版權符號。
下面是這三種字符特殊寫法的例子。
'\251' // "©"
'\xA9' // "©"
'\u00A9' // "©"
'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true
如果在非特殊字符前面使用反斜槓,則反斜槓會被省略。
'\a'
// "a"
上面代碼中,a
是一個正常字符,前面加反斜槓沒有特殊含義,反斜槓會被自動省略。
如果字符串的正常內容之中,需要包含反斜槓,則反斜槓前面需要再加一個反斜槓,用來對自身轉義。
"Prev \\ Next"
// "Prev \ Next"
6.3 字符串與數組
字符串可以被視爲字符數組,因此可以使用數組的方括號運算符,用來返回某個位置的字符(位置編號從0開始)。
var s = 'hello';
s[0] // "h"
s[1] // "e"
s[4] // "o"
// 直接對字符串使用方括號運算符
'hello'[1] // "e"
如果方括號中的數字超過字符串的長度,或者方括號中根本不是數字,則返回undefined
。
'abc'[3] // undefined
'abc'[-1] // undefined
'abc'['x'] // undefined
但是,字符串與數組的相似性僅此而已。實際上,無法改變字符串之中的單個字符。
var s = 'hello';
delete s[0];
s // "hello"
s[1] = 'a';
s // "hello"
s[5] = '!';
s // "hello"
上面代碼表示,字符串內部的單個字符無法改變和增刪,這些操作會默默地失敗。
6.4 length 屬性
length
屬性返回字符串的長度,該屬性也是無法改變的。
var s = 'hello';
s.length // 5
s.length = 3;
s.length // 5
6.5 Base64 轉碼
有時,文本里麪包含一些不可打印的符號,比如 ASCII 碼0到31的符號都無法打印出來,這時可以使用 Base64 編碼,將它們轉成可以打印的字符。另一個場景是,有時需要以文本格式傳遞二進制數據,那麼也可以使用 Base64 編碼。
所謂 Base64 就是一種編碼方法,可以將任意值轉成 0~9、A~Z、a-z、+
和/
這64個字符組成的可打印字符。使用它的主要目的,不是爲了加密,而是爲了不出現特殊字符,簡化程序的處理。
JavaScript 原生提供兩個 Base64 相關的方法。
btoa()
:任意值轉爲 Base64 編碼atob()
:Base64 編碼轉爲原來的值
var string = 'Hello World!';
btoa(string) // "SGVsbG8gV29ybGQh"
atob('SGVsbG8gV29ybGQh') // "Hello World!"
注意,這兩個方法不適合非 ASCII 碼的字符,會報錯。
btoa('你好') // 報錯
要將非 ASCII 碼字符轉爲 Base64 編碼,必須中間插入一個轉碼環節,再使用這兩個方法。
function b64Encode(str) {
return btoa(encodeURIComponent(str));
}
function b64Decode(str) {
return decodeURIComponent(atob(str));
}
b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"
思考題:
('b' + 'a' + + 'a' + 'a').toLowerCase() // banana
題解:
本文爲阮一峯老師的《JavaScript 教程》學習筆記,多數文字和示例來源於此書。