日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

解析JavaScript中的字符串类型与字符编码支持

發(fā)布時(shí)間:2024/1/17 javascript 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 解析JavaScript中的字符串类型与字符编码支持 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

JavaScript中的字符串也像Python那樣支持反斜杠的轉(zhuǎn)移,并且字符集方面默認(rèn)為Unicode,下面就來詳細(xì)解析JavaScript中的字符串類型與字符編碼支持


定義 字符串就是零個(gè)或多個(gè)排在一起的字符,放在單引號或雙引號之中。

`'abc'` `"abc"` 復(fù)制代碼

單引號字符串的內(nèi)部,可以使用雙引號。雙引號字符串的內(nèi)部,可以使用單引號。

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

上面兩個(gè)都是合法的字符串。

如果要在單引號字符串的內(nèi)部,使用單引號(或者在雙引號字符串的內(nèi)部,使用雙引號),就必須在內(nèi)部的單引號(或者雙引號)前面加上反斜杠,用來轉(zhuǎn)義。

`'Did she say \'Hello\'?'` `// "Did she say 'Hello'?"` `"Did she say \"Hello\"?"` `// "Did she say "Hello"?"` 復(fù)制代碼

由于HTML語言的屬性值使用雙引號,所以很多項(xiàng)目約定JavaScript語言的字符串只使用單引號,本教程就遵守這個(gè)約定。當(dāng)然,只使用雙引號也完全可以。重要的是,堅(jiān)持使用一種風(fēng)格,不要兩種風(fēng)格混合。

字符串默認(rèn)只能寫在一行內(nèi),分成多行將會(huì)報(bào)錯(cuò)。

`'a` `b` `c'` `// SyntaxError: Unexpected token ILLEGAL` 復(fù)制代碼

上面代碼將一個(gè)字符串分成三行,JavaScript就會(huì)報(bào)錯(cuò)。
如果長字符串必須分成多行,可以在每一行的尾部使用反斜杠。

`var` `longString =` `"Long \` `long \` `long \` `string"``;` `logString` `// "Long long long string"` 復(fù)制代碼

上面代碼表示,加了反斜杠以后,原來寫在一行的字符串,可以分成多行書寫。但是,輸出的時(shí)候還是單行,效果與寫在同一行完全一樣。注意,反斜杠的后面必須是換行符,而不能有其他字符(比如空格),否則會(huì)報(bào)錯(cuò)。

連接運(yùn)算符(+)可以連接多個(gè)單行字符串,將長字符串拆成多行書寫,輸出的時(shí)候也是單行。

`var` `longString =` `'Long '` `+` `'long '` `+` `'long '` `+` `'string'``;` 復(fù)制代碼

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

`(``function` `() {` `/*` `line 1` `line 2` `line 3` `*/``}).toString().split(``'\n'``).slice(1, -1).join(``'\n'``)` `// "line 1` `// line 2` `// line 3"` 復(fù)制代碼

上面的例子中,輸出的字符串就是多行。

轉(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) 復(fù)制代碼

上面這些字符前面加上反斜杠,都表示特殊含義。

`console.log(``'1\n2'``)` `// 1` `// 2` 復(fù)制代碼

上面代碼中,\n表示換行,輸出的時(shí)候就分成了兩行。
反斜杠還有三種特殊用法。

  • (1)\HHH
    反斜杠后面緊跟三個(gè)八進(jìn)制數(shù)(000到377),代表一個(gè)字符。HHH對應(yīng)該字符的Unicode碼點(diǎn),比如\251表示版權(quán)符號。顯然,這種方法只能輸出256種字符。

  • (2)\xHH
    \x后面緊跟兩個(gè)十六進(jìn)制數(shù)(00到FF),代表一個(gè)字符。HH對應(yīng)該字符的Unicode碼點(diǎn),比如\xA9表示版權(quán)符號。這種方法也只能輸出256種字符。

  • (3)\uXXXX
    \u后面緊跟四個(gè)十六進(jìn)制數(shù)(0000到FFFF),代表一個(gè)字符。HHHH對應(yīng)該字符的Unicode碼點(diǎn),比如\u00A9表示版權(quán)符號。

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

`'\251'` `// "?"` `'\xA9'` `// "?"` `'\u00A9'` `// "?"` `'172'` `===` `'z'` `// true` `'\x7A'` `===` `'z'` `// true` `'\u007A'` `===` `'z'` `// true`}//歡迎加入全棧開發(fā)交流圈一起學(xué)習(xí)交流:582735936]//面向1-3年前端人員} //幫助突破技術(shù)瓶頸,提升思維能力復(fù)制代碼

如果在非特殊字符前面使用反斜杠,則反斜杠會(huì)被省略。

`'\a'` `// "a"` 復(fù)制代碼

上面代碼中,a是一個(gè)正常字符,前面加反斜杠沒有特殊含義,反斜杠會(huì)被自動(dòng)省略。
如果字符串的正常內(nèi)容之中,需要包含反斜杠,則反斜杠前面需要再加一個(gè)反斜杠,用來對自身轉(zhuǎn)義。

`"Prev \\ Next"` `// "Prev \ Next"` 復(fù)制代碼

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

`var` `s =` `'hello'``;` `s[0]` `// "h"` `s[1]` `// "e"` `s[4]` `// "o"` 復(fù)制代碼

// 直接對字符串使用方括號運(yùn)算符
'hello'``[1] // "e"

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

`'abc'``[3]` `// undefined` `'abc'``[-1]` `// undefined` `'abc'``[``'x'``]` `// undefined` 復(fù)制代碼

但是,字符串與數(shù)組的相似性僅此而已。實(shí)際上,無法改變字符串之中的單個(gè)字符。

`var` `s =` `'hello'``;` `delete` `s[0];` `s` `// "hello"` `s[1] =` `'a'``;` `s` `// "hello"` `s[5] =` `'!'``;` `s `// "hello"` 復(fù)制代碼

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

字符串之所以類似于字符數(shù)組,實(shí)際是由于對字符串進(jìn)行方括號運(yùn)算時(shí),字符串會(huì)自動(dòng)轉(zhuǎn)換為一個(gè)字符串對象。

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

`var` `s =` `'hello'``;` `s.length` `// 5` `s.length = 3;` `s.length` `// 5` `s.length = 7;` `s.length` `// 5` 復(fù)制代碼

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

字符集 JavaScript使用Unicode字符集,也就是說在JavaScript內(nèi)部,所有字符都用Unicode表示。

不僅JavaScript內(nèi)部使用Unicode儲存字符,而且還可以直接在程序中使用Unicode,所有字符都可以寫成”\uxxxx”的形式,其中xxxx代表該字符的Unicode編碼。比如,\u00A9代表版權(quán)符號。

`var` `s =` `'\u00A9'``;` `s` `// "?"` 復(fù)制代碼

每個(gè)字符在JavaScript內(nèi)部都是以16位(即2個(gè)字節(jié))的UTF-16格式儲存。也就是說,JavaScript的單位字符長度固定為16位長度,即2個(gè)字節(jié)。

但是,UTF-16有兩種長度:對于U+0000到U+FFFF之間的字符,長度為16位(即2個(gè)字節(jié));對于U+10000到U+10FFFF之間的字符,長度為32位(即4個(gè)字節(jié)),而且前兩個(gè)字節(jié)在0xD800到0xDBFF之間,后兩個(gè)字節(jié)在0xDC00到0xDFFF之間。舉例來說,U+1D306對應(yīng)的字符為?,它寫成UTF-16就是0xD834 0xDF06。瀏覽器會(huì)正確將這四個(gè)字節(jié)識別為一個(gè)字符,但是JavaScript內(nèi)部的字符長度總是固定為16位,會(huì)把這四個(gè)字節(jié)視為兩個(gè)字符。

`var` `s =` `'\uD834\uDF06'``;` `s` `// "?"` `s.length` `// 2` `/^.$/.test(s)` `// false` `s.charAt(0)` `// ""` `s.charAt(1)` `// ""` `s.charCodeAt(0)` `// 55348` `s.charCodeAt(1)` `// 57094` 復(fù)制代碼

上面代碼說明,對于于U+10000到U+10FFFF之間的字符,JavaScript總是視為兩個(gè)字符(字符的length屬性為2),用來匹配單個(gè)字符的正則表達(dá)式會(huì)失敗(JavaScript認(rèn)為這里不止一個(gè)字符),charAt方法無法返回單個(gè)字符,charCodeAt方法返回每個(gè)字節(jié)對應(yīng)的十進(jìn)制值。

所以處理的時(shí)候,必須把這一點(diǎn)考慮在內(nèi)。對于4個(gè)字節(jié)的Unicode字符,假定C是字符的Unicode編號,H是前兩個(gè)字節(jié),L是后兩個(gè)字節(jié),則它們之間的換算關(guān)系如下。

`// 將大于U+FFFF的字符,從Unicode轉(zhuǎn)為UTF-16` `H = Math.floor((C - 0x10000) / 0x400) + 0xD800` `L = (C - 0x10000) % 0x400 + 0xDC00` `// 將大于U+FFFF的字符,從UTF-16轉(zhuǎn)為Unicode` `C = (H - 0xD800) * 0x400 + L - 0xDC00 + 0x10000` 復(fù)制代碼

下面的正則表達(dá)式可以識別所有UTF-16字符。

`([\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF])` 復(fù)制代碼

由于JavaScript引擎(嚴(yán)格說是ES5規(guī)格)不能自動(dòng)識別輔助平面(編號大于0xFFFF)的Unicode字符,導(dǎo)致所有字符串處理函數(shù)遇到這類字符,都會(huì)產(chǎn)生錯(cuò)誤的結(jié)果。如果要完成字符串相關(guān)操作,就必須判斷字符是否落在0xD800到0xDFFF這個(gè)區(qū)間。

下面是能夠正確處理字符串遍歷的函數(shù)。

`function` `getSymbols(string) {` `var` `length = string.length;` `var` `index = -1;` `var` `output = [];` `var` `character;` `var` `charCode;` `while` `(++index < length) {` `character = string.charAt(index);` `charCode = character.charCodeAt(0);` `if` `(charCode >= 0xD800 && charCode <= 0xDBFF) {` `output.push(character + string.charAt(++index));` `}` `else` `{` `output.push(character);` `}` `}` `return` `output;` `}` `var` `symbols = getSymbols(``'?'``);` `symbols.forEach(``function``(symbol) {` `// `});`}//歡迎加入全棧開發(fā)交流圈一起學(xué)習(xí)交流:582735936]//面向1-3年前端人員} //幫助突破技術(shù)瓶頸,提升思維能力復(fù)制代碼

替換(String.prototype.replace)、截取子字符串(String.prototype.substring, String.prototype.slice)等其他字符串操作,都必須做類似的處理。

Base64轉(zhuǎn)碼 Base64是一種編碼方法,可以將任意字符轉(zhuǎn)成可打印字符。使用這種編碼方法,主要不是為了加密,而是為了不出現(xiàn)特殊字符,簡化程序的處理。

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

* btoa():字符串或二進(jìn)制值轉(zhuǎn)為Base64編碼 * atob():Base64編碼轉(zhuǎn)為原來的編碼 `var` `string =` `'Hello World!'``;` `btoa(string)` `// "SGVsbG8gV29ybGQh"` `atob(``'SGVsbG8gV29ybGQh'``)` `// "Hello World!"` 復(fù)制代碼

這兩個(gè)方法不適合非ASCII碼的字符,會(huì)報(bào)錯(cuò)。

`btoa(``'你好'``)` `// Uncaught DOMException: The string to be encoded contains characters outside of the Latin1 range.` 復(fù)制代碼

要將非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'``)` `// "你好"`復(fù)制代碼


總結(jié)

以上是生活随笔為你收集整理的解析JavaScript中的字符串类型与字符编码支持的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。