(四)數(shù)據(jù)類(lèi)型之字符串基礎(chǔ)

1 概述


1.1定義

字符串就是零個(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 new morning"

上面兩個(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\"?"
// "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)字符串必須分成多行,可以在每一行的尾部使用反斜杠尼桶。

var longString = '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í)候也是單行稀颁。

var longString = 'Long '
  + 'long '
  + 'long '
  + 'string'; //longlongstring

如果想輸出多行字符串,有一種利用多行注釋的變通方法楣黍。

(function () { /*
line 1
line 2
line 3
*/}).toString().split('\n').slice(1, -1).join('\n')
// "line 1
// line 2
// line 3"

上面的例子中匾灶,輸出的字符串就是多行,里面關(guān)于字符串的處理方法toString() 租漂、split() 阶女、 join() 后面的相關(guān)章節(jié)會(huì)說(shuō)到。

1.2轉(zhuǎn)義

反斜杠(\)在字符串內(nèi)有特殊含義哩治,用來(lái)表示一些特殊字符秃踩,所以又稱(chēng)為轉(zhuǎn)義符。

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

\0 :null(\u0000)
\b :后退鍵(\u0008)
\f :換頁(yè)符(\u000C)
\n :換行符(\u000A)
\r :回車(chē)鍵(\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"
// "Prev \ Next"

1.3字符串與數(shù)組

字符串可以被視為字符數(shù)組狐史,因此可以使用數(shù)組的方括號(hào)運(yùn)算符痒给,用來(lái)返回某個(gè)位置的字符(位置編號(hào)從0開(kāi)始)。

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

// 直接對(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ù)組的相似性?xún)H此而已试吁。實(shí)際上,無(wú)法改變字符串之中的單個(gè)字符楼咳。

var s = 'hello';

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

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

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

上面代碼表示熄捍,字符串內(nèi)部的單個(gè)字符無(wú)法改變和增刪,這些操作會(huì)默默地失敗母怜。

1.4length 屬性

length屬性返回字符串的長(zhǎng)度余耽,該屬性也是無(wú)法改變的。

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

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

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

上面代碼表示字符串的length屬性無(wú)法改變苹熏,但是不會(huì)報(bào)錯(cuò)碟贾。

2 字符集



JavaScript 使用 Unicode 字符集。JavaScript 引擎內(nèi)部轨域,所有字符都用 Unicode 表示袱耽。

JavaScript 不僅以 Unicode 儲(chǔ)存字符,還允許直接在程序中使用 Unicode 碼點(diǎn)表示字符干发,即將字符寫(xiě)成\uxxxx的形式朱巨,其中xxxx代表該字符的 Unicode 碼點(diǎn)。比如铐然,\u00A9代表版權(quán)符號(hào)蔬崩。

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

解析代碼的時(shí)候,JavaScript 會(huì)自動(dòng)識(shí)別一個(gè)字符是字面形式表示搀暑,還是 Unicode 形式表示沥阳。輸出給用戶(hù)的時(shí)候,所有字符都會(huì)轉(zhuǎn)成字面形式自点。

var f\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)度可能是不正確的日熬。

3 Base64 轉(zhuǎn)碼(此章節(jié)做參考,不是重點(diǎ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)的值

var string = '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è)方法。

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

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

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

本文大量參考借鑒了阮一峰老師的博客《JavaScript 標(biāo)準(zhǔn)參考教程》,他的文章使我受益匪淺科侈,在此表示由衷的感謝载佳!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市臀栈,隨后出現(xiàn)的幾起案子刚盈,更是在濱河造成了極大的恐慌,老刑警劉巖挂脑,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異欲侮,居然都是意外死亡崭闲,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)威蕉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)刁俭,“玉大人,你說(shuō)我怎么就攤上這事韧涨‰蛊荩” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵虑粥,是天一觀的道長(zhǎng)如孝。 經(jīng)常有香客問(wèn)我,道長(zhǎng)娩贷,這世上最難降的妖魔是什么第晰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮彬祖,結(jié)果婚禮上茁瘦,老公的妹妹穿的比我還像新娘。我一直安慰自己储笑,他們只是感情好甜熔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著突倍,像睡著了一般腔稀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上羽历,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天烧颖,我揣著相機(jī)與錄音,去河邊找鬼窄陡。 笑死炕淮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的跳夭。 我是一名探鬼主播涂圆,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼们镜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了润歉?” 一聲冷哼從身側(cè)響起模狭,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎踩衩,沒(méi)想到半個(gè)月后嚼鹉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驱富,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年锚赤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片褐鸥。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡线脚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出叫榕,到底是詐尸還是另有隱情浑侥,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布晰绎,位于F島的核電站寓落,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏荞下。R本人自食惡果不足惜零如,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望锄弱。 院中可真熱鬧考蕾,春花似錦、人聲如沸会宪。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)掸鹅。三九已至塞帐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間巍沙,已是汗流浹背葵姥。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留句携,地道東北人榔幸。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親削咆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子牍疏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

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

  • 第2章 基本語(yǔ)法 2.1 概述 基本句法和變量 語(yǔ)句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,149評(píng)論 0 13
  • 概述 定義 字符串就是零個(gè)或多個(gè)排在一起的字符拨齐,放在單引號(hào)或雙引號(hào)之中鳞陨。 單引號(hào)字符串的內(nèi)部,可以使用雙引號(hào)瞻惋。雙引...
    許先生__閱讀 352評(píng)論 0 1
  • 前言 最先接觸編程的知識(shí)是在大學(xué)里面歼狼,大學(xué)里面學(xué)了一些基礎(chǔ)的知識(shí)掏导,c語(yǔ)言,java語(yǔ)言蹂匹,單片機(jī)的匯編語(yǔ)言等;大學(xué)畢...
    oceanfive閱讀 3,087評(píng)論 0 7
  • 字符的 Unicode 表示法 codePointAt() String.fromCodePoint() 字符串的...
    卞卞村長(zhǎng)L閱讀 750評(píng)論 0 0
  • ES6加強(qiáng)了對(duì)Unicode的支持凹蜈,并且擴(kuò)展了字符串對(duì)象限寞。 字符的Unicode表示法: JavaScript允許...
    呼呼哥閱讀 784評(píng)論 0 0