字符串和字符串對象


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>
ejs模板解析

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, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;");

    // Don't escape special characters in the template.
    s += templateData[i];
  }
  return s;
}
過濾Html字符串

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM