JavaScript中的字符串也像Python那樣支持反斜槓的轉移,而且字符集方面默認爲Unicode,下面就來詳細解析JavaScript中的字符串類型與字符編碼支持javascript
定義 字符串就是零個或多個排在一塊兒的字符,放在單引號或雙引號之中。php
`'abc'`
`"abc"`
複製代碼
單引號字符串的內部,可使用雙引號。雙引號字符串的內部,可使用單引號。前端
'key = "value"'
"It's a long journey"
java
上面兩個都是合法的字符串。正則表達式
若是要在單引號字符串的內部,使用單引號(或者在雙引號字符串的內部,使用雙引號),就必須在內部的單引號(或者雙引號)前面加上反斜槓,用來轉義。數組
`'Did she say \'Hello\'?'`
`// "Did she say 'Hello'?"`
`"Did she say \"Hello\"?"`
`// "Did she say "Hello"?"`
複製代碼
因爲HTML語言的屬性值使用雙引號,因此不少項目約定JavaScript語言的字符串只使用單引號,本教程就遵照這個約定。固然,只使用雙引號也徹底能夠。重要的是,堅持使用一種風格,不要兩種風格混合。瀏覽器
字符串默認只能寫在一行內,分紅多行將會報錯。ruby
`'a`
`b`
`c'`
`// SyntaxError: Unexpected token ILLEGAL`
複製代碼
上面代碼將一個字符串分紅三行,JavaScript就會報錯。
若是長字符串必須分紅多行,能夠在每一行的尾部使用反斜槓。bash
`var` `longString =` `"Long \` `long \` `long \` `string"``;` `logString` `// "Long long long string"` 複製代碼
上面代碼表示,加了反斜槓之後,原來寫在一行的字符串,能夠分紅多行書寫。可是,輸出的時候仍是單行,效果與寫在同一行徹底同樣。注意,反斜槓的後面必須是換行符,而不能有其餘字符(好比空格),不然會報錯。ide
鏈接運算符(+)能夠鏈接多個單行字符串,將長字符串拆成多行書寫,輸出的時候也是單行。
`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"`
複製代碼
上面的例子中,輸出的字符串就是多行。
轉義 反斜槓(\)在字符串內有特殊含義,用來表示一些特殊字符,因此又稱爲轉義符。
須要用反斜槓轉義的特殊字符,主要有下面這些:
* \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),表明一個字符。HHHH對應該字符的Unicode碼點,好比\u00A9表示版權符號。
下面是這三種字符特殊寫法的例子。
`'\251'` `// "©"`
`'\xA9'` `// "©"`
`'\u00A9'` `// "©"`
`'172'` `===` `'z'` `// true`
`'\x7A'` `===` `'z'` `// true`
`'\u007A'` `===` `'z'` `// true`
}//歡迎加入全棧開發交流圈一塊兒學習交流:582735936
]//面向1-3年前端人員
} //幫助突破技術瓶頸,提高思惟能力
複製代碼
若是在非特殊字符前面使用反斜槓,則反斜槓會被省略。
`'\a'`
`// "a"`
複製代碼
上面代碼中,a是一個正常字符,前面加反斜槓沒有特殊含義,反斜槓會被自動省略。
若是字符串的正常內容之中,須要包含反斜槓,則反斜槓前面須要再加一個反斜槓,用來對自身轉義。
`"Prev \\ Next"`
`// "Prev \ Next"`
複製代碼
字符串與數組 字符串能夠被視爲字符數組,所以可使用數組的方括號運算符,用來返回某個位置的字符(位置編號從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"`
複製代碼
上面代碼表示,字符串內部的單個字符沒法改變和增刪,這些操做會默默地失敗。
字符串之因此相似於字符數組,實際是因爲對字符串進行方括號運算時,字符串會自動轉換爲一個字符串對象。
length屬性 length屬性返回字符串的長度,該屬性也是沒法改變的。
`var` `s =` `'hello'``;`
`s.length` `// 5`
`s.length = 3;`
`s.length` `// 5`
`s.length = 7;`
`s.length` `// 5`
複製代碼
上面代碼表示字符串的length屬性沒法改變,可是不會報錯。
字符集 JavaScript使用Unicode字符集,也就是說在JavaScript內部,全部字符都用Unicode表示。
不只JavaScript內部使用Unicode儲存字符,並且還能夠直接在程序中使用Unicode,全部字符均可以寫成」\uxxxx」的形式,其中xxxx表明該字符的Unicode編碼。好比,\u00A9表明版權符號。
`var` `s =` `'\u00A9'``;`
`s` `// "©"`
複製代碼
每一個字符在JavaScript內部都是以16位(即2個字節)的UTF-16格式儲存。也就是說,JavaScript的單位字符長度固定爲16位長度,即2個字節。
可是,UTF-16有兩種長度:對於U+0000到U+FFFF之間的字符,長度爲16位(即2個字節);對於U+10000到U+10FFFF之間的字符,長度爲32位(即4個字節),並且前兩個字節在0xD800到0xDBFF之間,後兩個字節在0xDC00到0xDFFF之間。舉例來講,U+1D306對應的字符爲𝌆,它寫成UTF-16就是0xD834 0xDF06。瀏覽器會正確將這四個字節識別爲一個字符,可是JavaScript內部的字符長度老是固定爲16位,會把這四個字節視爲兩個字符。
`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`
複製代碼
上面代碼說明,對於於U+10000到U+10FFFF之間的字符,JavaScript老是視爲兩個字符(字符的length屬性爲2),用來匹配單個字符的正則表達式會失敗(JavaScript認爲這裏不止一個字符),charAt方法沒法返回單個字符,charCodeAt方法返回每一個字節對應的十進制值。
因此處理的時候,必須把這一點考慮在內。對於4個字節的Unicode字符,假定C是字符的Unicode編號,H是前兩個字節,L是後兩個字節,則它們之間的換算關係以下。
`// 將大於U+FFFF的字符,從Unicode轉爲UTF-16`
`H = Math.floor((C - 0x10000) / 0x400) + 0xD800`
`L = (C - 0x10000) % 0x400 + 0xDC00`
`// 將大於U+FFFF的字符,從UTF-16轉爲Unicode`
`C = (H - 0xD800) * 0x400 + L - 0xDC00 + 0x10000`
複製代碼
下面的正則表達式能夠識別全部UTF-16字符。
`([\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF])`
複製代碼
因爲JavaScript引擎(嚴格說是ES5規格)不能自動識別輔助平面(編號大於0xFFFF)的Unicode字符,致使全部字符串處理函數遇到這類字符,都會產生錯誤的結果。若是要完成字符串相關操做,就必須判斷字符是否落在0xD800到0xDFFF這個區間。
下面是可以正確處理字符串遍歷的函數。
`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) {`
`// `});` }//歡迎加入全棧開發交流圈一塊兒學習交流:582735936 ]//面向1-3年前端人員 } //幫助突破技術瓶頸,提高思惟能力 複製代碼
替換(String.prototype.replace)、截取子字符串(String.prototype.substring, String.prototype.slice)等其餘字符串操做,都必須作相似的處理。
Base64轉碼 Base64是一種編碼方法,能夠將任意字符轉成可打印字符。使用這種編碼方法,主要不是爲了加密,而是爲了避免出現特殊字符,簡化程序的處理。
JavaScript原生提供兩個Base64相關方法。
* btoa():字符串或二進制值轉爲Base64編碼
* atob():Base64編碼轉爲原來的編碼
`var` `string =` `'Hello World!'``;`
`btoa(string)` `// "SGVsbG8gV29ybGQh"`
`atob(``'SGVsbG8gV29ybGQh'``)` `// "Hello World!"`
複製代碼
這兩個方法不適合非ASCII碼的字符,會報錯。
`btoa(``'你好'``)`
`// Uncaught DOMException: The string to be encoded contains characters outside of the Latin1 range.`
複製代碼
要將非ASCII碼字符轉爲Base64編碼,必須中間插入一個轉碼環節,再使用這兩個方法。
`function` `b64Encode(str) {`
`return` `btoa(encodeURIComponent(str));`
`}`
`function` `b64Decode(str) {`
`return` `decodeURIComponent(atob(str));`
`}`
`b64Encode(``'你好'``)` `// "JUU0JUJEJUEwJUU1JUE1JUJE"`
`b64Decode(``'JUU0JUJEJUEwJUU1JUE1JUJE'``)` `// "你好"`複製代碼