定義
字符串就是零個(gè)或多個(gè)排在一起的字符豆胸,放在單引號(hào)或雙引號(hào)之中常柄。
'abc'"abc"
單引號(hào)字符串的內(nèi)部,可以使用雙引號(hào)摇予。雙引號(hào)字符串的內(nèi)部汽绢,可以使用單引號(hào)。
'key = "value"'"It's a long journey"
上面兩個(gè)都是合法的字符串侧戴。
如果要在單引號(hào)字符串的內(nèi)部宁昭,使用單引號(hào)跌宛,就必須在內(nèi)部的單引號(hào)前面加上反斜杠,用來(lái)轉(zhuǎn)義积仗。雙引號(hào)字符串內(nèi)部使用雙引號(hào)疆拘,也是如此。
'Did she say \'Hello\'?'// "Did she say 'Hello'?""Did she say \"Hello\"?"http:// "Did she say "Hello"?"
由于 HTML 語(yǔ)言的屬性值使用雙引號(hào)寂曹,所以很多項(xiàng)目約定 JavaScript 語(yǔ)言的字符串只使用單引號(hào)入问,本教程遵守這個(gè)約定。當(dāng)然稀颁,只使用雙引號(hào)也完全可以芬失。重要的是堅(jiān)持使用一種風(fēng)格,不要一會(huì)使用單引號(hào)表示字符串匾灶,一會(huì)又使用雙引號(hào)表示棱烂。
字符串默認(rèn)只能寫(xiě)在一行內(nèi),分成多行將會(huì)報(bào)錯(cuò)阶女。
'a
b
c'// SyntaxError: Unexpected token ILLEGAL
上面代碼將一個(gè)字符串分成三行颊糜,JavaScript 就會(huì)報(bào)錯(cuò)。
如果長(zhǎng)字符串必須分成多行秃踩,可以在每一行的尾部使用反斜杠衬鱼。
varlongString='Long \long \long \string';longString// "Long long long string"
上面代碼表示,加了反斜杠以后憔杨,原來(lái)寫(xiě)在一行的字符串鸟赫,可以分成多行書(shū)寫(xiě)。但是消别,輸出的時(shí)候還是單行抛蚤,效果與寫(xiě)在同一行完全一樣。注意寻狂,反斜杠的后面必須是換行符岁经,而不能有其他字符(比如空格),否則會(huì)報(bào)錯(cuò)蛇券。
連接運(yùn)算符(+)可以連接多個(gè)單行字符串缀壤,將長(zhǎng)字符串拆成多行書(shū)寫(xiě),輸出的時(shí)候也是單行纠亚。
varlongString='Long '+'long '+'long '+'string';
如果想輸出多行字符串塘慕,有一種利用多行注釋的變通方法。
(function(){/*
line 1
line 2
line 3
*/}).toString().split('\n').slice(1,-1).join('\n')// "line 1// line 2// line 3"
上面的例子中菜枷,輸出的字符串就是多行苍糠。
轉(zhuǎn)義
反斜杠(\)在字符串內(nèi)有特殊含義叁丧,用來(lái)表示一些特殊字符啤誊,所以又稱為轉(zhuǎn)義符岳瞭。
需要用反斜杠轉(zhuǎn)義的特殊字符,主要有下面這些蚊锹。
\0?:null(\u0000)
\b?:后退鍵(\u0008)
\f?:換頁(yè)符(\u000C)
\n?:換行符(\u000A)
\r?:回車鍵(\u000D)
\t?:制表符(\u0009)
\v?:垂直制表符(\u000B)
\'?:?jiǎn)我?hào)(\u0027)
\"?:雙引號(hào)(\u0022)
\\?:反斜杠(\u005C)
上面這些字符前面加上反斜杠瞳筏,都表示特殊含義。
console.log('1\n2')// 1// 2
上面代碼中牡昆,\n表示換行姚炕,輸出的時(shí)候就分成了兩行。
反斜杠還有三種特殊用法丢烘。
(1)\HHH
反斜杠后面緊跟三個(gè)八進(jìn)制數(shù)(000到377)柱宦,代表一個(gè)字符。HHH對(duì)應(yīng)該字符的 Unicode 碼點(diǎn)播瞳,比如\251表示版權(quán)符號(hào)掸刊。顯然,這種方法只能輸出256種字符赢乓。
(2)\xHH
\x后面緊跟兩個(gè)十六進(jìn)制數(shù)(00到FF)忧侧,代表一個(gè)字符。HH對(duì)應(yīng)該字符的 Unicode 碼點(diǎn)牌芋,比如\xA9表示版權(quán)符號(hào)蚓炬。這種方法也只能輸出256種字符。
(3)\uXXXX
\u后面緊跟四個(gè)十六進(jìn)制數(shù)(0000到FFFF)躺屁,代表一個(gè)字符肯夏。XXXX對(duì)應(yīng)該字符的 Unicode 碼點(diǎn),比如\u00A9表示版權(quán)符號(hào)犀暑。
下面是這三種字符特殊寫(xiě)法的例子熄捍。
'\251'// "?"'\xA9'// "?"'\u00A9'// "?"'\172'==='z'// true'\x7A'==='z'// true'\u007A'==='z'// true
如果在非特殊字符前面使用反斜杠,則反斜杠會(huì)被省略母怜。
'\a'// "a"
上面代碼中余耽,a是一個(gè)正常字符,前面加反斜杠沒(méi)有特殊含義苹熏,反斜杠會(huì)被自動(dòng)省略碟贾。
如果字符串的正常內(nèi)容之中,需要包含反斜杠轨域,則反斜杠前面需要再加一個(gè)反斜杠袱耽,用來(lái)對(duì)自身轉(zhuǎn)義。
"Prev \\ Next"http:// "Prev \ Next"
字符串與數(shù)組
字符串可以被視為字符數(shù)組干发,因此可以使用數(shù)組的方括號(hào)運(yùn)算符朱巨,用來(lái)返回某個(gè)位置的字符(位置編號(hào)從0開(kāi)始)。
vars='hello';s[0]// "h"s[1]// "e"s[4]// "o"http:// 直接對(duì)字符串使用方括號(hào)運(yùn)算符'hello'[1]// "e"
如果方括號(hào)中的數(shù)字超過(guò)字符串的長(zhǎng)度枉长,或者方括號(hào)中根本不是數(shù)字冀续,則返回undefined琼讽。
'abc'[3]// undefined'abc'[-1]// undefined'abc'['x']// undefined
但是,字符串與數(shù)組的相似性僅此而已洪唐。實(shí)際上钻蹬,無(wú)法改變字符串之中的單個(gè)字符。
vars='hello';deletes[0];s// "hello"s[1]='a';s// "hello"s[5]='!';s// "hello"
上面代碼表示凭需,字符串內(nèi)部的單個(gè)字符無(wú)法改變和增刪问欠,這些操作會(huì)默默地失敗。
length 屬性
length屬性返回字符串的長(zhǎng)度粒蜈,該屬性也是無(wú)法改變的顺献。
vars='hello';s.length// 5s.length=3;s.length// 5s.length=7;s.length// 5
上面代碼表示字符串的length屬性無(wú)法改變,但是不會(huì)報(bào)錯(cuò)枯怖。
字符集
JavaScript 使用 Unicode 字符集滚澜。JavaScript 引擎內(nèi)部,所有字符都用 Unicode 表示嫁怀。
JavaScript 不僅以 Unicode 儲(chǔ)存字符设捐,還允許直接在程序中使用 Unicode 碼點(diǎn)表示字符,即將字符寫(xiě)成\uxxxx的形式塘淑,其中xxxx代表該字符的 Unicode 碼點(diǎn)萝招。比如,\u00A9代表版權(quán)符號(hào)存捺。
vars='\u00A9';s// "?"
解析代碼的時(shí)候槐沼,JavaScript 會(huì)自動(dòng)識(shí)別一個(gè)字符是字面形式表示,還是 Unicode 形式表示捌治。輸出給用戶的時(shí)候岗钩,所有字符都會(huì)轉(zhuǎn)成字面形式。
varf\u006F\u006F='abc';foo// "abc"
上面代碼中肖油,第一行的變量名foo是 Unicode 形式表示兼吓,第二行是字面形式表示。JavaScript 會(huì)自動(dòng)識(shí)別森枪。
我們還需要知道视搏,每個(gè)字符在 JavaScript 內(nèi)部都是以16位(即2個(gè)字節(jié))的 UTF-16 格式儲(chǔ)存。也就是說(shuō)县袱,JavaScript 的單位字符長(zhǎng)度固定為16位長(zhǎng)度浑娜,即2個(gè)字節(jié)。
但是式散,UTF-16 有兩種長(zhǎng)度:對(duì)于碼點(diǎn)在U+0000到U+FFFF之間的字符筋遭,長(zhǎng)度為16位(即2個(gè)字節(jié));對(duì)于碼點(diǎn)在U+10000到U+10FFFF之間的字符,長(zhǎng)度為32位(即4個(gè)字節(jié))漓滔,而且前兩個(gè)字節(jié)在0xD800到0xDBFF之間编饺,后兩個(gè)字節(jié)在0xDC00到0xDFFF之間岩馍。舉例來(lái)說(shuō),碼點(diǎn)U+1D306對(duì)應(yīng)的字符為??濒旦,它寫(xiě)成 UTF-16 就是0xD834 0xDF06豆巨。
JavaScript 對(duì) UTF-16 的支持是不完整的,由于歷史原因剂娄,只支持兩字節(jié)的字符,不支持四字節(jié)的字符。這是因?yàn)?JavaScript 第一版發(fā)布的時(shí)候畅形,Unicode 的碼點(diǎn)只編到U+FFFF,因此兩字節(jié)足夠表示了诉探。后來(lái)日熬,Unicode 納入的字符越來(lái)越多,出現(xiàn)了四字節(jié)的編碼肾胯。但是竖席,JavaScript 的標(biāo)準(zhǔn)此時(shí)已經(jīng)定型了,統(tǒng)一將字符長(zhǎng)度限制在兩字節(jié)敬肚,導(dǎo)致無(wú)法識(shí)別四字節(jié)的字符毕荐。上一節(jié)的那個(gè)四字節(jié)字符??,瀏覽器會(huì)正確識(shí)別這是一個(gè)字符艳馒,但是 JavaScript 無(wú)法識(shí)別憎亚,會(huì)認(rèn)為這是兩個(gè)字符。
'??'.length// 2
上面代碼中弄慰,JavaScript 認(rèn)為??的長(zhǎng)度為2第美,而不是1。
總結(jié)一下陆爽,對(duì)于碼點(diǎn)在U+10000到U+10FFFF之間的字符什往,JavaScript 總是認(rèn)為它們是兩個(gè)字符(length屬性為2)。所以處理的時(shí)候慌闭,必須把這一點(diǎn)考慮在內(nèi)恶守,也就是說(shuō),JavaScript 返回的字符串長(zhǎng)度可能是不正確的贡必。
Base64 轉(zhuǎn)碼
有時(shí)兔港,文本里面包含一些不可打印的符號(hào),比如 ASCII 碼0到31的符號(hào)都無(wú)法打印出來(lái)仔拟,這時(shí)可以使用 Base64 編碼衫樊,將它們轉(zhuǎn)成可以打印的字符。另一個(gè)場(chǎng)景是,有時(shí)需要以文本格式傳遞二進(jìn)制數(shù)據(jù)科侈,那么也可以使用 Base64 編碼载佳。
所謂 Base64 就是一種編碼方法,可以將任意值轉(zhuǎn)成 0~9臀栈、A~Z蔫慧、a-z、+和/這64個(gè)字符組成的可打印字符权薯。使用它的主要目的姑躲,不是為了加密,而是為了不出現(xiàn)特殊字符盟蚣,簡(jiǎn)化程序的處理黍析。
JavaScript 原生提供兩個(gè) Base64 相關(guān)的方法。
btoa():任意值轉(zhuǎn)為 Base64 編碼
atob():Base64 編碼轉(zhuǎn)為原來(lái)的值
varstring='Hello World!';btoa(string)// "SGVsbG8gV29ybGQh"atob('SGVsbG8gV29ybGQh')// "Hello World!"
注意屎开,這兩個(gè)方法不適合非 ASCII 碼的字符阐枣,會(huì)報(bào)錯(cuò)。
btoa('你好')// 報(bào)錯(cuò)
要將非 ASCII 碼字符轉(zhuǎn)為 Base64 編碼奄抽,必須中間插入一個(gè)轉(zhuǎn)碼環(huán)節(jié)蔼两,再使用這兩個(gè)方法。
functionb64Encode(str){returnbtoa(encodeURIComponent(str));}functionb64Decode(str){returndecodeURIComponent(atob(str));}b64Encode('你好')// "JUU0JUJEJUEwJUU1JUE1JUJE"b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE')// "你好"