ES6學習筆記第四章

字符串的擴展

    

  1 字符的Unicode表示法

  js允許採用\uxxxx形式表示一個字符,其中xxxx表示字符的碼點。

  "\u0061"

      //a

  ES6做出了一點改進,大括號表示法與四字節的UTF-16編碼是等價的,只要將碼點放入大括號,就能正確解讀。

    

    2 codePointAt()

    js內部,字符以UTF-16的格式存儲,每個字符固定爲2字節。對於那些需要4個字節存儲的字符,js會認爲他們是2個字符。ES6提供了codePointAt()方法,能夠正確處理4個字節存儲的字符,返回一個字符的碼點。


    codePointAt()方法是測試一個字符由2個還是4個字節組成的最簡單方法。

    function is32Bit(c){
        return c.codePointAt(0)>0xFFFF;
    }


    3 String.fromCodePoint()

    ES5提供了String.fromCharCode方法,用於從碼點返回對應字符,但是這個方法不能識別32位的UTF-16字符。ES6提供了String.fromCodePoint方法,彌補了String.fromCharCode方法的不足。

    該方法作用上正好和codePointAt方法相反。


    4 字符串的遍歷器接口

    ES6爲字符串添加了遍歷器接口,使字符串可以由for...of循環遍歷。

    for (let codePoint of 'foo'){

        console.log(codePoint);

    }

    // "f"

    //"o"

    //"o"

    這個遍歷器最大的優點是可以識別大於0xFFFF的碼點,傳統for循環無法識別。

    

    5 at()

    ES6爲字符串實例提供了at方法,等同於ES5的charAt方法,並可以識別Unicode編號大於0xFFFF的字符。


    6 normalize()

    

    7 includes(), startsWith(), endsWith()

      js中只有indexOf方法可以用來確定一個字符串是否包含在另一個字符串中。

      ES6則又提供了3種新方法

      includes() :返回布爾值,表示是否找了到參數字符串 

      startsWith() :返回布爾值, 表示參數字符串是否在源字符串的頭部。

      endsWith(): 返回布爾值,表示參數字符串是否在源字符串的尾部。


    8 repeat()

      repeat 方法返回一個新的字符串,表示將原字符串重複n次。

      參數是負數或者Infinity,會報錯。小數會向下取整。如果是字符串,會先轉換成數字。


    9 padStart(), padEnd()

      ES7推出字符串補全長度的功能。如果某個字符串未達到指定長度,會在頭部或者尾部補全。

      padStart 和padEnd分別接受兩個參數,第一個用來指定字符串的最小長度,第二個則是用來補全的字符串。

      如果原字符串的長度等於或者大於指定的最小長度,則返回原字符串。

      如果省略第二個參數,則會用空格來補全。


    10 模板字符串

       模板字符串是增強版的字符串,用反引號(`)標識。他可以當做普通字符串使用,也可以用來定義多行字符串,或者在字符串中嵌入變量。

      $("#result").append(`

          There are <b>${basket.count}</b> items

          in your basket, <em>${basket.onSale}</em>

          are on sale!                                      

      `);

        如果在模板字符串中需要使用反引號,則在其前面要用反斜槓轉義。

        var greeting = `\`yo\`world!`;

        在模板字符串中使用多行字符,所有空格和縮進都會被保留在輸出中。

        

        大括號內可以放入任意的js表達式,可以進行運算,以及引用對象屬性。

         

        模板字符串中還能調用函數

        如果大括號中的值不是字符串,將按照一般的規則轉化成爲字符串。

        

    11.實例:模板編譯

       

    下面,我們來看一個通過模板字符串,生成正式模板的實例。

    

    var template = `

    <ul>

      <% for(var i=0; i < data.supplies.length; i++) { %>

        <li><%= data.supplies[i] %></li>

      <% } %>

    </ul>

    `;

    上面代碼在模板字符串之中,放置了一個常規模板。該模板使用<%...%>放置JavaScript代碼,使用<%= ... %>輸出JavaScript表達式。

    

    怎麼編譯這個模板字符串呢?

    

    一種思路是將其轉換爲JavaScript表達式字符串。

    

    echo('<ul>');

    for(var i=0; i < data.supplies.length; i++) {

      echo('<li>');

      echo(data.supplies[i]);

      echo('</li>');

    };

    echo('</ul>');

    這個轉換使用正則表達式就行了。

    

    var evalExpr = /<%=(.+?)%>/g;

    var expr = /<%([\s\S]+?)%>/g;

    

    template = template

      .replace(evalExpr, '`); \n  echo( $1 ); \n  echo(`')

      .replace(expr, '`); \n $1 \n  echo(`');

    

    template = 'echo(`' + template + '`);';

    然後,將template封裝在一個函數裏面返回,就可以了。

    

    var script =

    `(function parse(data){

      var output = "";

    

      function echo(html){

        output += html;

      }

    

      ${ template }

    

      return output;

    })`;

    

    return script;

    將上面的內容拼裝成一個模板編譯函數compile。

    

    function compile(template){

      var evalExpr = /<%=(.+?)%>/g;

      var expr = /<%([\s\S]+?)%>/g;

    

      template = template

        .replace(evalExpr, '`); \n  echo( $1 ); \n  echo(`')

        .replace(expr, '`); \n $1 \n  echo(`');

    

      template = 'echo(`' + template + '`);';

    

      var script =

      `(function parse(data){

        var output = "";

    

        function echo(html){

          output += html;

        }

    

        ${ template }

    

        return output;

      })`;

    

      return script;

    }

    compile函數的用法如下。

    

    var parse = eval(compile(template)); //eval()計算字符串方法。

    div.innerHTML = parse({ supplies: [ "broom", "mop", "cleaner" ] });

    //   <ul>

    //     <li>broom</li>

    //     <li>mop</li>

    //     <li>cleaner</li>

    //   </ul>


    12. 標籤模板

      模板字符串可以緊跟在一個函數後面,該函數將被調用來處理這個模板字符串。稱之爲“標籤模板”功能。標籤模板其實不是模板,而是函數調用的一種特殊形式。“標籤”指的就是函數,緊跟在後面的模板字符串就是它的參數。

      

    但是,如果模板字符裏面有變量,就不是簡單的調用了,而是會將模板字符串先處理成多個參數,再調用函數。

    

    var a = 5;

    var b = 10;

    

    tag`Hello ${ a + b } world ${ a * b }`;

    // 等同於

    tag(['Hello ', ' world ', ''], 15, 50);

    上面代碼中,模板字符串前面有一個標識名tag,它是一個函數。整個表達式的返回值,就是tag函數處理模板字符串後的返回值。

    

    函數tag依次會接收到多個參數。

    

    function tag(stringArr, value1, value2){

      // ...

    }

    

    // 等同於

    

    function tag(stringArr, ...values){

      // ...

    }

    tag函數的第一個參數是一個數組,該數組的成員是模板字符串中那些沒有變量替換的部分,也就是說,變量替換隻發生在數組的第一個成員與第二個成員之間、第二個成員與第三個成員之間,以此類推。

    

    tag函數的其他參數,都是模板字符串各個變量被替換後的值。由於本例中,模板字符串含有兩個變量,因此tag會接受到value1和value2兩個參數。

    

    tag函數所有參數的實際值如下。

    

    第一個參數:['Hello ', ' world ', '']

    第二個參數: 15

    第三個參數:50

    也就是說,tag函數實際上以下面的形式調用。

    

    tag(['Hello ', ' world ', ''], 15, 50)

    我們可以按照需要編寫tag函數的代碼。下面是tag函數的一種寫法,以及運行結果。

    

    var a = 5;

    var b = 10;

    

    function tag(s, v1, v2) {

      console.log(s[0]);

      console.log(s[1]);

      console.log(s[2]);

      console.log(v1);

      console.log(v2);

    

      return "OK";

    }

    

    tag`Hello ${ a + b } world ${ a * b}`;

    // "Hello "

    // " world "

    // ""

    // 15

    // 50

    // "OK"


    13 String.raw()

      ES6還爲原聲的String對象提供了raw方法。

      String.raw方法往往用來充當模板字符串的處理函數,返回一個反斜線都會被轉義(既反斜線前加反斜線)的字符串,對應於替換變量後的模板字符串

      如果原字符串的反斜線已經轉義,那麼String.raw不會做任何處理。

      

      String.raw方法可以作爲處理模板字符串的基本方法,它會將所有變量替換,而且對斜槓進行轉義,方便下一步作爲字符串來使用。

    

      String.raw方法也可以作爲正常的函數使用。這時,它的第一個參數,應該是一個具有raw屬性的對象,且raw屬性的值應該是一個數組。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章