1.寫法
1.普通表示
字符串可以使用單引號或者雙引號。多數JS項目約定使用單引號(')。
可以用單引號包含雙引號,也可以用雙引號包含單引號。
'ab"c"dd'或者"abc'd'e"
如果想單引號包含單引號,或者雙引號包含雙引號,需要使用轉義符號:
'abc\'de' // abc'de "abc\"de" // abc"de
2. 長字符串
如果想寫長字符串,不能直接換行,會報錯,有2種常見寫法。
var str = "Hello world, I'm Lyra"; // 如果想分行寫 // 1)在最后加\ var str = "Hello world,\ I'm Lyra"; // 2) 使用+拼接字符
3. 模版字符串
如果想保留書寫格式,使用模版字符串。
var str = `a b`
1.模板編譯
用js實現html模板。
將模版字符串轉為正式的模板,以下是ejs模板示例:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>ejs模版解析</title> </head> <body> <div id="root"></div> <script> var data = { supplies: ['boom', 'cleaner', 'mop'] } var template = ` <ul> <% for(let i=0; i<data.supplies.length;i++) {%> <li><%=data.supplies[i]%></li> <%}%> </ul> `; /* 中間形式代碼: echo(<ul>); for(let i=0; i<data.supplies.length;i++) { echo(<li>) echo(data.supplies[i]) echo(</li>) } echo(</ul>); */ // 寫一個編譯函數 function compile(template) { // 使用正則表達式解析模板符號,將其轉為上面中間形式代碼 regExp = /<%([\s\S]+?)%>/g; regExpEqul = /<%=(.+?)%>/g; // 先執行這個替換,否則會錯亂 var template = template .replace(regExpEqul, '`); \n echo( $1 ); \n echo(`') .replace(regExp, '`); $1 \n echo(`') var template = 'echo(`' + template + '`)'; // 定義html輸出函數 var output = ""; function echo(html) { output += html; } // 返回一個可以傳入數據的函數 return function parse(data) { eval(template); return output; } } const innerHtml = compile(template)(data) window.root.innerHTML = innerHtml; </script> </body> </html>
2. 模板標簽
非小括號的函數調用方式;使用模版字符串調用。
let message = SaferHTML`<p>${sender} has sent you a message.</p>`; // SaferHTML 是個標簽函數
實際傳參形式如下
let message = SafeHTML( ["<p>", " has sent you a message.</p>", raw: Array(2)], ${sender})
可以用來過濾Html字符串,防惡意輸入

let message = SaferHTML`<p>${sender} has sent you a message.</p>`; function SaferHTML(templateData) { let s = templateData[0]; for (let i = 1; i < arguments.length; i++) { let arg = String(arguments[i]); // Escape special characters in the substitution. s += arg.replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">"); // Don't escape special characters in the template. s += templateData[i]; } return s; }
2.字符的Unicode碼表示
1)\HHH 三位8進制數 // 只能表示256個字符
2)\xHH 兩位16進制數 // 只能表示256個字符
3)\uHHHH 四位16進制數
4) \u{字符} // 大括號內的數字是16進制的數字,即使沒有0x符號。 ES6表示法,可以展示大於0xFFFF的值
// 示例:版權符號 '\251' // ©️ '\xA9' // ©️ '\u00A9' // ©️
s引擎內部每個字符都是utf-16格式,16位存儲(2個字節)。
但是在ES5中,對於超過\u0000-\uFFFF范圍的字符來說,js會將其分成兩個字符(4個字節)。str.length的長度為2。
在ES6中,可以使用大括號來表示碼點大於0xFFFF的字符,如:
'\u1D306' // 在ES5中因為超過\uFFFF,會被解析成"\u1D30" + 6, 即"ᴰ6" // ES5如果想要正確顯示大於0xFFFF的字符,需要將其寫成第一個字符\uD800-\uDBFF之間,第二個字符位於\uDC00-\uDFFF之間的拼接字符。 '\uD834\uDF06' // "𝌆"--正確 // ES6中就可以直接用大括號表示 '\u{1D306}' //"𝌆"
碼點大於0xFFFF的字符,可以被for...of...遍歷器正確遍歷
3.轉義字符
需要使用反斜杠轉義的主要有:
\r 回車 \n 換行 \\ 反斜桿 \' 單引號 \" 雙引號
4. Base64編碼
Base64,顧名思義,就是基於64個字符。就是將任意值轉為0-9,A-Z,a-z,+,/這64個字符組成的可打印字符。
用途:1)顯示特殊字符,比如ASCII碼的前31位。2)將二進制數據(比如圖片)轉為文本
有兩個方法:
btoa(str); // 轉為Base64 atob(str); // 從Base64轉為原來的值
上面的方法僅適用於ASCII碼,對於諸如漢字等非ASCII碼,需要先通過encodeURIComponent處理
var str ="你好"; btoa(encodeURIComponent(str)); //"JUU0JUJEJUEwJUU1JUE1JUJE" decodeURIComponent(atob("JUU0JUJEJUEwJUU1JUE1JUJE")) // "你好"
5.字符串對象方法
1.靜態方法--返回碼點對應字符
1) String.fromCharCode(碼點,碼點,,,)
返回碼點對應的字符,使用於0x0000-0xFFFF之間的字符,超出的可以拆分成兩個字符
2) String.fromCodePoint(碼點,,,)
作用同上,但是作為ES6新增方法,可以解析大於0xFFFF的字符。
String.fromCodePoint(0x20bb7); // "𠮷"
3)String.raw`str`---標簽函數
將模版字符串的所有變量替換,並且將斜杠轉義
String.raw`Hi\n${2+3}!` === "Hi\\n5!"; // true // 但是在頁面上展示是"Hi\n5!" // 相當於 String.raw({raw: ['Hi\\n','!'],},5);
2. 實例方法--基本方法
1)String.prototype.charAt([index]) ---根據位置返回字符(0x0000-0xFFFF)
index可以省略,默認是0,即第一個位置。
和字符串按照數組索引取值類似,不同點在於[]取值超過范圍返回undefined,
該方法超過有效index,返回“”空字符串。
2) String.prototype.charCodeAt([index]) --- 根據位置返回碼點(十進制)(0x0000-0xFFFF)
index默認是0,結果想轉16進制,可以調用toString(16)
3) String.prototype.codePointAt([index]) --- 根據位置返回碼點(十進制)
功能和2)相同,但是可以識別大於0xFFFF的字符。
'ad'.codePointAt(1); // 100
4)String.prototype.normalize()---Unicode碼統一化
返回結果相同的不同表示形式統一化
有四種參數: NFC,NFD,NFKC,NFKD
'\u01D1'.normalize() === '\u004F\u030C'.normalize()
3.實例方法---字符串變更
1) String.prototype.concat(多個參數) ---拼接字符串
會將不是字符串的參數轉為字符串
2)String.prototype.slice(start, end) ---截取字符串
遵循[)左閉右開原則,如果參數<0,表示從后面數。
如果start>end,返回“”
3)String.prototype.substring(start, end) --- 截取字符串
遵循[)左閉右開原則,如果參數<0, 將負數轉為0.
如果start>end,交換兩者的值。
4)String.prototype.substr(start,length) --- 截取字符串
如果start<0, 從后面數;
如果length<0, 將length置為0
5)String.prototype.toLowerCase(),String.prototype.toUpperCase()--轉大小寫
6)String.prototype.split(string/RegExp[, limit]) --- 分割字符串
第一個參數可以是字符串或者正則表達式,第二個限制返回的長度。
如果正則表達式帶有括號,則括號匹配的內容也會返回
'aaa*a*'.split(/a*/); // ['', '*', '*'] 'aaa*a*'.split(/(a*)/); // ['', 'aaa' , '*', 'a', '*']
7)String.prototype.replace(string/RegExp, string/function)---替換字符串
不改變原字符串。
一般只替換第一個匹配的字符
'abaaaaaac'.replace('a', 'A'); //"Abaaaaaac"
當正則表達式使用g修飾符時,會替換所有匹配的字符
'abaaaaaac'.replace(/a/g, 'A') //"AbAAAAAAc"
第二個參數如果是字符串,可以有幾個特殊值。
1) '$&' // 被替換的字符 'abc'.replace(/b/, '$&'); // abc 2)'$`' // 被替換內容前面的所有字符 'dddabc'.replace(/b/, '$`'); //"dddadddac" 3) '$\'' // 被替換內容后面的所有字符 'abcd'.replace(/b/, '$\''); //acdcd 4) '$n' // 組匹配的第n個內容 'abc'.replace(/(.)(.)/g, '$&-$1-$2-$`-$\'-$$'); // "ab-a-b--c-$c" //由上可知,$&==ab,$1 == a,$2==b,$` == '', $\' === c 5)$$ // 表示$符號
6)$<組名> // 表示具名組匹配的引用;和$n性質一樣
第二個參數如果是函數,函數參數為:($&, $1,.,,...$n, $&索引, 原字符串,groups)
8)String.prototype.repeat(n)---將字符串重復n次
如果n是Infinity或者<=-1, 返回RangeError;
如果-1<n<1, n默認取0;
如果是其他值,向下取整
9) String.prototype.trim()----去除首尾空白字符 ES5
String.prototype.trimStart()--- 去除首部空白字符ES2019
String.prototype.trimEnd() --- 去除尾部空白字符ES2019
10)padStart(length, str),padEnd(length, str) --- 補全字符串
length表示補全后的字符串長度,原字符串長度大於length,返回原值;
str用於補全的字符,默認是空格。
'05'.padStart(10,'YYYY-MM-DD'); // "YYYY-MM-05"
4. 實例方法---字符串查找
1)indexOf(str[, start])---從start向后查找第一個目標字符串的位置
lastIndexOf(str[, start])---從start向前開始查找第一個目標字符串的位置
start表示開始查找的位置
'abcdaddfdsa'.indexOf('a'); // 0 'abcdaddfdsa'.indexOf('a',4); // 4 'abcdaddfdsa'.indexOf('a',-1); // 0 當start<0時,按照0處理
'abcdaddfdsa'.lastIndexOf('a',3); // 0
2) search(str/RegExp) --- 從頭查找目標字符串第一個出現的位置
作用和indexOf相同,不同點在於search可以使用正則表達式
'abca'.search('a'); // 0 'abca'.search(/a/); // 0
3)match(str/RegExp) --- 用數組返回查找的結果
如果查找失敗,返回null;
當為正則表達式時,如果有g修飾符,返回所有的匹配結果,忽略組匹配。
當為正則表達式時,如果沒有g修飾符,或者為字符串時,會返回組匹配,並且返回input和index屬性。
'abca'.match(/(.)/g); // ["a", "b", "c", "a"] 'abca'.match(/(.)/); // ["a", "a", index: 0, input: "abca", groups: undefined]
//其中第一個是匹配結果,第二個是組匹配,index是匹配的位置,input是原字符串
4)matchAll(RegExp) --- 用遍歷器返回所有匹配結果。返回的是遍歷器。
和3)相比, 可以遍歷整個字符串,還可以獲得組匹配。
matchAll返回的是一個遍歷器;好處是比數組節約資源;
可以通過...擴展運算符和Array.from()可以將其轉為數組。
const a = 'abca'.matchAll(/(.)/g); // RegExpStringIterator {} [...a]; /* [ ["a", "a", index: 0, input: "abca", groups: undefined], ["b", "b", index: 0, input: "abca", groups: undefined], ["c", "c", index: 0, input: "abca", groups: undefined], ["a", "a", index: 0, input: "abca", groups: undefined] ] */
5)includes(str)---通過布爾值返回查找結果
6)startsWith(str, start) --- 通過布爾值是否以str開頭
start參數表示查找的起始位置
'abc'.startsWith('a'); // true 'abc'.startsWith('a', 1); // false
7)endsWith(str, beforeIndex)---通過布爾值是否以str結尾
beforeIndex表示前beforeIndex個字符。
'abc'.endsWith('a',1); // true 前一個字符以a結尾 'abc'.endsWith('a'); // false
5. 實例方法-字符串比較
str1.localeCompare(str2) --- 比較字符串大小
按照自然語言比較,不同於比較運算符
結果是1, 表示str1 > str2
結果是0,表示str1 === str2
結果是-1,表示str1 < str2
'B'.localeCompare('a'); // 1 前者大 'B'>'a'// false 前者小
該方法還可以用來比較漢字,按照漢語拼音的順序
'按'.localeCompare('們') // -1 '我'.localeCompare('們') // 1