ES6模板字面量

来源:http://www.cnblogs.com/xiaohuochai/archive/2017/07/25/7234281.html
-Advertisement-
Play Games

[1]基本用法 [2]多行字元串 [3]變數占位符 [4]標簽模板 [5]raw() ...


前面的話

  JS 的字元串相對其他語言來說功能總是有限的,事實上,ES5中一直缺乏許多特性,如多行字元串、字元串格式化、HTML轉義等。ES6通過模板字面量的方式進行了填補,模板字面量試著跳出JS已有的字元串體系,通過一些全新的方法來解決類似的問題。本文將詳細介紹ES6模板字面量

 

基本用法

  模板字面量是增強版的字元串,它用反引號(`)標識

let message = `Hello world!`;
console.log(message); // "Hello world!"
console.log(typeof message); // "string"
console.log(message.length); // 12

   以上代碼中,使用模板字面量語法創建一個字元串,並賦值給message變數,這時變數的值與一個普通的字元串無異

  如果想在字元串中包含反引號,只需使用反斜杠( \ )轉義即可

let message = `\`Hello\` world!`;
console.log(message); // "`Hello` world!"
console.log(typeof message); // "string"
console.log(message.length); // 14

 

多行字元串

  自javascript誕生起,開發者們就一直在尋找一種能創建多行字元串的方法。如果使用雙引號或單引號,字元串一定要在同一行才行

【反斜杠】

  由於javascript長期以來一直存在一個語法bug,在換行之前的反斜線( \ )可以承接下一行的代碼,於是可以利用這個bug來創建多行字元串

var message = "Multiline \
string";
console.log(message); // "Multiline string"

  message 字元串列印輸出時不會有換行,因為反斜線被視為延續符號而不是新行的符號。為了在輸出中顯示換行,需要手動加入換行符

var message = "Multiline \n\
string";
// "Multiline 
// string"
console.log(message); 

  在所有主流的 JS 引擎中,此代碼都會輸出兩行,但是該行為被認定為一個 bug ,並且許多開發者都建議應避免這麼做

  在ES6之前,通常都依靠數組或字元串的拼接來創建多行字元串

var message = ["Multiline ","string"].join("\n");
let message = "Multiline \n" +"string";

  JS一直以來都不支持多行字元串,開發者的種種解決方法都不夠完美

【反引號】

  ES6 的模板字面量使多行字元串更易創建,因為它不需要特殊的語法,只需在想要的位置直接換行即可,此處的換行會同步出現在結果中

let message = `Multiline
string`;
// "Multiline
// string"
console.log(message); 
console.log(message.length); // 16

  在反引號之內的所有空白符都是字元串的一部分,因此需要特別留意縮進

let message = `Multiline
                             string`;
// "Multiline
                            // string"
console.log(message); 
console.log(message.length); //24

  以上代碼中,模板字面量第二行前面的所有空白符都被視為字元串自身的一部分

  如果一定要通過適當的縮進來對齊文本,可以考慮在多行模板字面量的第一行空置併在後面的幾行縮進

let html = `
<div>
    <h1>Title</h1>
</div>`.trim();

  以上代碼中,模板字面量的第一行沒有任何文本,第二行才有內容。 HTML標簽的縮進增強了可讀性,之後再調用trim()方法移除了起始的空行

  當然,也可以在模板字面量中使用 \n 來指示換行的插入位置

let message = `Multiline\nstring`;
// "Multiline
// string" 
console.log(message); 
console.log(message.length); // 16

 

變數占位符

  模板字面量看上去僅僅是普通JS字元串的升級版,但二者之間真正的區別在於模板字面量的變數占位符。變數占位符允許將任何有效的JS表達式嵌入到模板字面量中,並將其結果輸出為字元串的一部分

  變數占位符由起始的 ${ 與結束的 } 來界定,之間允許放入任意的 JS 表達式。最簡單的變數占位符允許將本地變數直接嵌入到結果字元串中

let name = "Nicholas",
message = `Hello, ${name}.`;
console.log(message); // "Hello, Nicholas."

  占位符 ${name} 會訪問本地變數 name ,並將其值插入到 message 字元串中。 message變數會立即保留該占位符的結果

  既然占位符是JS表達式,那麼可替換的就不僅僅是簡單的變數名。可以輕易嵌入運算符、函數調用等

let count = 10,
price = 0.25,
message = `${count} items cost $${(count * price).toFixed(2)}.`;
console.log(message); // "10 items cost $2.50."
function fn() {
  return "Hello World";
}

`foo ${fn()} bar`
// foo Hello World bar

  模板字面量本身也是 JS 表達式,因此可以將模板字面量嵌入到另一個模板字面量內部

let name = "Nicholas",
    message = `Hello, ${
        `my name is ${ name }`
    }.`;
console.log(message); // "Hello, my name is Nicholas."

 

標簽模板

  模板字面量真正的威力來自於標簽模板,每個模板標簽都可以執行模板字面量上的轉換並返回最終的字元串值。標簽指的是在模板字面量第一個反引號'`'前方標註的字元串

let message = tag`Hello world`;

  在這個示例中, tag 就是應用到 `Hello world` 模板字面量上的模板標簽

【定義標簽】

  標簽可以是一個函數,調用時傳入加工過的模板字面量各部分數據,但必須結合每個部分來創建結果。第一個參數是一個數組,包含Javascript解釋過後的字面量字元串,它之後的所有參數都是每一個占位符的解釋值

  標簽函數通常使用不定參數特性來定義占位符,從而簡化數據處理的過程

function tag(literals, ...substitutions) {
  // 返回一個字元串
}

  為了進一步理解傳遞給tag函數的參數,查看以下代碼

let count = 10,
price = 0.25,
message = passthru`${count} items cost $${(count * price).toFixed(2)}.`;

  如果有一個名為passthru()的函數,那麼作為一個模板字面量標簽,它會接受3個參數首先是一個literals數組,包含以下元素

  1、第一個占位符前的空字元串("")

  2、第一、二個占位符之間的字元串(" items cost $")

  3、第二個占位符後的字元串(".")

  下一個參數是變數count的解釋值,傳參為10,它也成為了substitutions數組裡的第一個元素

  最後一個參數是(count*price).toFixed(2)的解釋值,傳參為2.50,它是substitutions數組裡的第二個元素

  [註意]literals里的第一個元素是一個空字元串,這確保了literals[0]總是字元串的始端,就像literals[literals.length-1]總是字元串的結尾一樣。substitutions的數量總比literals少一個,這也意味著表達式substitutions. Iength === literals. Iength-1的結果總為true

var a = 5;
var b = 10;

tag`Hello ${ a + b } world ${ a * b }`;
// 等同於
tag(['Hello ', ' world ', ''], 15, 50);

  通過這種模式,我們可以將literals和substitutions兩個數組交織在一起重組結果字元串。先取出literals中的首個元素,再取出substitution中的首個元素,然後交替繼續取出每一個元素,直到字元串拼接完成。於是可以通過從兩個數組中交替取值的方式模擬模板字面量的預設行為

function passthru(literals, ...substitutions) {
    let result = "";
    // 僅使用 substitution 的元素數量來進行迴圈
    for (let i = 0; i < substitutions.length; i++) {
        result += literals[i];
        result += substitutions[i];
    }
    // 添加最後一個字面量
    result += literals[literals.length - 1];
    return result;
}
let count = 10,
price = 0.25,
message = passthru`${count} items cost $${(count * price).toFixed(2)}.`;
console.log(message); // "10 items cost $2.50."

  這個示例定義了一個passthru標簽,模擬模板字面量的預設行為,展示了一次轉換過程。此處的小竅門是使用substitutions.length來為迴圈計數

【應用】

  “標簽模板”的一個重要應用,就是過濾HTML字元串,防止用戶輸入惡意內容

var message =
  SaferHTML`<p>${sender} has sent you a message.</p>`;

function SaferHTML(templateData) {
  var s = templateData[0];
  for (var i = 1; i < arguments.length; i++) {
    var 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;
}

  上面代碼中,sender變數往往是用戶提供的,經過SaferHTML函數處理,裡面的特殊字元都會被轉義

var sender = '<script>alert("abc")</script>'; // 惡意代碼
var message = SaferHTML`<p>${sender} has sent you a message.</p>`;

console.log(message);// <p>&lt;script&gt;alert("abc")&lt;/script&gt; has sent you a message.</p>

  標簽模板的另一個應用,就是多語言轉換(國際化處理)

i18n`Welcome to ${siteName}, you are visitor number ${visitorNumber}!`
// "歡迎訪問xxx,您是第xxxx位訪問者!"

  模板字元串本身並不能取代模板引擎,因為沒有條件判斷和迴圈處理功能,但是通過標簽函數,可以自己添加這些功能

// 下麵的hashTemplate函數
// 是一個自定義的模板處理函數
var libraryHtml = hashTemplate`
  <ul>
    #for book in ${myBooks}
      <li><i>#{book.title}</i> by #{book.author}</li>
    #end
  </ul>
`;

 

raw()

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

let message1 = `Multiline\nstring`,
message2 = String.raw`Multiline\nstring`;
console.log(message1); // "Multiline
// string"
console.log(message2); // "Multiline\\nstring"
String.raw`Hi\n${2+3}!`;
// "Hi\\n5!"

String.raw`Hi\u000A!`;
// 'Hi\\u000A!'

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

String.raw`Hi\\n`// "Hi\\n"

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

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

String.raw({ raw: 'test' }, 0, 1, 2);// 't0e1s2t'

// 等同於
String.raw({ raw: ['t','e','s','t'] }, 0, 1, 2);

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 冒泡排序<script type="text/javascript"> var arr = [3,7,6,2,1,5]; 定義一個交換使用的中間變數var temp = 0;for(i=0;i<arr.length;i++){ for(j=0;j<arr.length;j++){如果下一個元素小於當 ...
  • cookie、session cookie:在瀏覽器保存一些數據,每次請求都會帶過來 *不安全、有限(4K) session:保存數據,保存在服務端 *安全、無限 session:基於cookie實現的 *cookie中會有一個session的ID,伺服器利用sessionid找到session文件 ...
  • package com.log; import java.io.IOException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Enumeration; import java.util.Li... ...
  • 安裝 API 可以通過body-parser 對象創建中間件,當接收到客戶端請求時所有的中間件都會給req.body 添加屬性,請求體為空,則解析為空{} (或者出現錯誤)。 bodyParser.json(options) 中間件只會解析 json ,允許請求提任意Unicode編碼支持 gzip ...
  • <canvas>標簽定義了一塊畫布,畫布可以在網頁中繪製2D和3D圖象,現在先學習如何繪製2D圖象,繪製3D圖象屬於WebGL的內容(也就是網頁版的OpenGL,3D圖形介面)。 屬性 <canvas>只有width和height兩個屬性。如果沒有設置width和height屬性,canvas的預設 ...
  • Layout Controls Auto Layout Ext JS4中的容器的預設佈局是自動佈局。這個佈局管理器會自動地將組件放在一個容器中。 Fit Layout Fit佈局安排了容器的內容完全占據空間,它適合於容器的大小。Fit佈局通常用於具有單個項目的容器。Fit佈局是Card佈局的基類 A ...
  • //settime($("#getPhoneCode"),60); function settime($obj, time) { if (time == 0) { $obj.attr("disabled", false); $obj.css("background", "#f38401").css(... ...
  • jquery table 元素操作-創建|數據填充|重置|隱藏行 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...