字符串

概述

定義

字符串就是零個或多個排在一起的字符营密,放在單引號或雙引號之中。

'abc'
"abc"

單引號字符串的內(nèi)部冰蘑,可以使用雙引號和泌。雙引號字符串的內(nèi)部,可以使用單引號祠肥。

'key = "value"'
"It's a long journey"

上面兩個都是合法的字符串武氓。

如果要在單引號字符串的內(nèi)部,使用單引號仇箱,就必須在內(nèi)部的單引號前面加上反斜杠县恕,用來轉(zhuǎn)義。雙引號字符串內(nèi)部使用雙引號剂桥,也是如此忠烛。

'Did she say \'Hello\'?'
// "Did she say 'Hello'?"

"Did she say \"Hello\"?"
// "Did she say "Hello"?"

由于 HTML 語言的屬性值使用雙引號,所以很多項目約定 JavaScript 語言的字符串只使用單引號权逗,本教程遵守這個約定美尸。當(dāng)然,只使用雙引號也完全可以斟薇。重要的是堅持使用一種風(fēng)格师坎,不要一會使用單引號表示字符串,一會又使用雙引號表示堪滨。

字符串默認(rèn)只能寫在一行內(nèi)胯陋,分成多行將會報錯。

'a
b
c'
// SyntaxError: Unexpected token ILLEGAL

上面代碼將一個字符串分成三行椿猎,JavaScript 就會報錯惶岭。

如果長字符串必須分成多行寿弱,可以在每一行的尾部使用反斜杠犯眠。

var longString = 'Long \
long \
long \
string';

longString
// "Long long long string"

上面代碼表示,加了反斜杠以后症革,原來寫在一行的字符串筐咧,可以分成多行書寫。但是,輸出的時候還是單行量蕊,效果與寫在同一行完全一樣铺罢。注意,反斜杠的后面必須是換行符残炮,而不能有其他字符(比如空格)韭赘,否則會報錯。

連接運算符(+)可以連接多個單行字符串势就,將長字符串拆成多行書寫泉瞻,輸出的時候也是單行。

var longString = '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)有特殊含義鞭达,用來表示一些特殊字符,所以又稱為轉(zhuǎn)義符皇忿。

需要用反斜杠轉(zhuǎn)義的特殊字符畴蹭,主要有下面這些。

  • \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

反斜杠后面緊跟三個八進制數(shù)(000377)铺峭,代表一個字符墓怀。HHH對應(yīng)該字符的 Unicode 碼點,比如\251表示版權(quán)符號卫键。顯然傀履,這種方法只能輸出256種字符。

(2)\xHH

\x后面緊跟兩個十六進制數(shù)(00FF)莉炉,代表一個字符钓账。HH對應(yīng)該字符的 Unicode 碼點,比如\xA9表示版權(quán)符號絮宁。這種方法也只能輸出256種字符梆暮。

(3)\uXXXX

\u后面緊跟四個十六進制數(shù)(0000FFFF),代表一個字符绍昂。HHHH對應(yīng)該字符的 Unicode 碼點啦粹,比如\u00A9表示版權(quán)符號偿荷。

下面是這三種字符特殊寫法的例子。

'\251' // "?"
'\xA9' // "?"
'\u00A9' // "?"

'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true

如果在非特殊字符前面使用反斜杠唠椭,則反斜杠會被省略跳纳。

'\a'
// "a"

上面代碼中,a是一個正常字符贪嫂,前面加反斜杠沒有特殊含義寺庄,反斜杠會被自動省略。

如果字符串的正常內(nèi)容之中力崇,需要包含反斜杠铣揉,則反斜杠前面需要再加一個反斜杠,用來對自身轉(zhuǎn)義餐曹。

"Prev \\ Next"
// "Prev \ Next"

字符串與數(shù)組

字符串可以被視為字符數(shù)組逛拱,因此可以使用數(shù)組的方括號運算符,用來返回某個位置的字符(位置編號從0開始)台猴。

var s = 'hello';
s[0] // "h"
s[1] // "e"
s[4] // "o"

// 直接對字符串使用方括號運算符
'hello'[1] // "e"

如果方括號中的數(shù)字超過字符串的長度朽合,或者方括號中根本不是數(shù)字,則返回undefined饱狂。

'abc'[3] // undefined
'abc'[-1] // undefined
'abc'['x'] // undefined

但是曹步,字符串與數(shù)組的相似性僅此而已。實際上休讳,無法改變字符串之中的單個字符讲婚。

var s = 'hello';

delete s[0];
s // "hello"

s[1] = 'a';
s // "hello"

s[5] = '!';
s // "hello"

上面代碼表示,字符串內(nèi)部的單個字符無法改變和增刪俊柔,這些操作會默默地失敗筹麸。

length 屬性

length屬性返回字符串的長度,該屬性也是無法改變的雏婶。

var s = 'hello';
s.length // 5

s.length = 3;
s.length // 5

s.length = 7;
s.length // 5

上面代碼表示字符串的length屬性無法改變物赶,但是不會報錯。

字符集

JavaScript 使用 Unicode 字符集留晚。JavaScript 引擎內(nèi)部酵紫,所有字符都用 Unicode 表示。

JavaScript 不僅以 Unicode 儲存字符错维,還允許直接在程序中使用 Unicode 碼點表示字符奖地,即將字符寫成\uxxxx的形式,其中xxxx代表該字符的 Unicode 碼點赋焕。比如参歹,\u00A9代表版權(quán)符號。

var s = '\u00A9';
s // "?"

解析代碼的時候宏邮,JavaScript 會自動識別一個字符是字面形式表示泽示,還是 Unicode 形式表示。輸出給用戶的時候蜜氨,所有字符都會轉(zhuǎn)成字面形式械筛。

var f\u006F\u006F = 'abc';
foo // "abc"

上面代碼中,第一行的變量名foo是 Unicode 形式表示飒炎,第二行是字面形式表示埋哟。JavaScript 會自動識別。

我們還需要知道郎汪,每個字符在 JavaScript 內(nèi)部都是以16位(即2個字節(jié))的 UTF-16 格式儲存赤赊。也就是說,JavaScript 的單位字符長度固定為16位長度煞赢,即2個字節(jié)抛计。

但是,UTF-16 有兩種長度:對于碼點在U+0000U+FFFF之間的字符照筑,長度為16位(即2個字節(jié))吹截;對于碼點在U+10000U+10FFFF之間的字符,長度為32位(即4個字節(jié))凝危,而且前兩個字節(jié)在0xD8000xDBFF之間波俄,后兩個字節(jié)在0xDC000xDFFF之間。舉例來說蛾默,碼點U+1D306對應(yīng)的字符為??懦铺,它寫成 UTF-16 就是0xD834 0xDF06

JavaScript 對 UTF-16 的支持是不完整的支鸡,由于歷史原因冬念,只支持兩字節(jié)的字符,不支持四字節(jié)的字符牧挣。這是因為 JavaScript 第一版發(fā)布的時候刘急,Unicode 的碼點只編到U+FFFF,因此兩字節(jié)足夠表示了浸踩。后來叔汁,Unicode 納入的字符越來越多,出現(xiàn)了四字節(jié)的編碼检碗。但是据块,JavaScript 的標(biāo)準(zhǔn)此時已經(jīng)定型了,統(tǒng)一將字符長度限制在兩字節(jié)折剃,導(dǎo)致無法識別四字節(jié)的字符另假。上一節(jié)的那個四字節(jié)字符??,瀏覽器會正確識別這是一個字符怕犁,但是 JavaScript 無法識別边篮,會認(rèn)為這是兩個字符己莺。

'??'.length // 2

上面代碼中,JavaScript 認(rèn)為??的長度為2戈轿,而不是1凌受。

總結(jié)一下,對于碼點在U+10000U+10FFFF之間的字符思杯,JavaScript 總是認(rèn)為它們是兩個字符(length屬性為2)胜蛉。所以處理的時候,必須把這一點考慮在內(nèi)色乾,也就是說誊册,JavaScript 返回的字符串長度可能是不正確的。

Base64 轉(zhuǎn)碼

有時暖璧,文本里面包含一些不可打印的符號案怯,比如 ASCII 碼0到31的符號都無法打印出來,這時可以使用 Base64 編碼澎办,將它們轉(zhuǎn)成可以打印的字符殴泰。另一個場景是,有時需要以文本格式傳遞二進制數(shù)據(jù)浮驳,那么也可以使用 Base64 編碼悍汛。

所謂 Base64 就是一種編碼方法,可以將任意值轉(zhuǎn)成 0~9至会、A~Z离咐、a-z、+/這64個字符組成的可打印字符奉件。使用它的主要目的宵蛀,不是為了加密,而是為了不出現(xiàn)特殊字符县貌,簡化程序的處理术陶。

JavaScript 原生提供兩個 Base64 相關(guān)的方法。

  • btoa():任意值轉(zhuǎn)為 Base64 編碼
  • atob():Base64 編碼轉(zhuǎn)為原來的值
var string = 'Hello World!';
btoa(string) // "SGVsbG8gV29ybGQh"
atob('SGVsbG8gV29ybGQh') // "Hello World!"

注意煤痕,這兩個方法不適合非 ASCII 碼的字符梧宫,會報錯。

btoa('你好') // 報錯

要將非 ASCII 碼字符轉(zhuǎn)為 Base64 編碼摆碉,必須中間插入一個轉(zhuǎn)碼環(huán)節(jié)塘匣,再使用這兩個方法。

function b64Encode(str) {
  return btoa(encodeURIComponent(str));
}

function b64Decode(str) {
  return decodeURIComponent(atob(str));
}

b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"

參考鏈接

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末巷帝,一起剝皮案震驚了整個濱河市忌卤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌楞泼,老刑警劉巖驰徊,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笤闯,死亡現(xiàn)場離奇詭異,居然都是意外死亡棍厂,警方通過查閱死者的電腦和手機颗味,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來勋桶,“玉大人,你說我怎么就攤上這事侥猬±裕” “怎么了?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵退唠,是天一觀的道長鹃锈。 經(jīng)常有香客問我,道長瞧预,這世上最難降的妖魔是什么屎债? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮垢油,結(jié)果婚禮上盆驹,老公的妹妹穿的比我還像新娘。我一直安慰自己滩愁,他們只是感情好躯喇,可當(dāng)我...
    茶點故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著硝枉,像睡著了一般廉丽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上妻味,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天正压,我揣著相機與錄音,去河邊找鬼责球。 笑死焦履,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雏逾。 我是一名探鬼主播裁良,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼校套!你這毒婦竟也來了价脾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤笛匙,失蹤者是張志新(化名)和其女友劉穎侨把,沒想到半個月后犀变,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡秋柄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年获枝,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骇笔。...
    茶點故事閱讀 38,683評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡省店,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出笨触,到底是詐尸還是另有隱情懦傍,我是刑警寧澤,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布芦劣,位于F島的核電站粗俱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏虚吟。R本人自食惡果不足惜系吩,卻給世界環(huán)境...
    茶點故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一腻格、第九天 我趴在偏房一處隱蔽的房頂上張望间唉。 院中可真熱鬧笙各,春花似錦、人聲如沸邦鲫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掂碱。三九已至怜姿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間疼燥,已是汗流浹背沧卢。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留醉者,地道東北人但狭。 一個月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像撬即,于是被迫代替她去往敵國和親立磁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,566評論 2 349

推薦閱讀更多精彩內(nèi)容