1. 程式人生 > >深入ES6 (四) 字串的括展

深入ES6 (四) 字串的括展

第四章 字串的括展

ES6加強了對Unicode的支援,並且擴充套件了字串物件。本章把重點放在ES6對物件方法的括展上,至於字元Unicode表示法的加強,則不打算詳細展開。本章主要包括:

  1. 模板字串與標籤模板
  2. 字串括展方法
  3. 字元的Unicode表示法(簡介)

4.1模板字串與模板標籤

模板字串

在第一章我們已經大體介紹了模板字串的使用方法,先讓我們回顧一下。

使用模板字串可以輕鬆的在字串中進行變數的替換。注意使用模板時,最外層為“號(反引號),變數使用{}的花括號中可以是任意表達式。如果表示式的返回值不是字串,則將按照一般規則轉化為字串。比如如果大括號中是一個物件的話,將預設呼叫物件的toString方法。

let name = 'Kyle';
let foo = `學生${name}正在學習ES6`;

再比如:

let student = {
    name : 'Kyle',
    toString: function () {
        return 'Agent' + this.name
    }
};
let foo = `學生${student}正在學習ES6`;
console.log(foo); // 輸出:學生AgentKyle正在學習ES6

這解決了ES5中換行和引入變數瑣碎不便的問題。下面是一個使用模板字串拼接和普通字串拼接DOM並插入到頁面的例子,你可以明顯的發現前者要方便很多:

let arr = ['first', 'second', 'third'];

let ul = `<ul>
            <li>${arr[0]}</li>
            <li>${arr[1]}</li>
            <li>${arr[2]}</li>
         </ul>`;

let normalUl = '<ul>\
                    <li>'+arr[0]+'</li>\
                    <li>'+arr[1]+'</li>\
                    <li>'+arr[2]+'</li>\
                </ul>';

document.getElementById('container').innerHTML = ul;
document.getElementById('normal-container').innerHTML = normalUl;

上面的程式碼使用的兩種方式呈現的最終效果是一致的,但現在我們稍作修改,把下面的兩個innerHTML改為innerText,執行結果:

如果使用模板字串表示多行字串,所有的空格和縮排會被保留在輸出中。檢視原始碼可以發現,瀏覽器在處理時使用了br標籤。

標籤模板

標籤模板其實並非模板,而是一種函式的呼叫方式。標籤其實就是一個函式,其格式是:

標籤函式`模板字串`

其中標籤函式會被預設注入若干個引數,第一個引數是一個數組,其中的元素是模板字串非變數與變數之間的各個部分,隨後的引數是模板字串中的變數被替換後的值。顯然,如果模板字串中有n個變數,標籤函式就會有n+1個引數。這可能聽起來有些抽象,我們看下面的例子就一目瞭然了:

let student = {
    id:'2014556698',
    name:'AgentKyle'
};

function tagFun(arr, ...args) {
    arr.forEach((item) => {
        console.log(item);
    });

    args.forEach((item) => {
        console.log(item);
    })

    return 'ok!'
}

tagFun`學生姓名:${student.name},學生id:${student.id};`;  // =>ok!

執行結果,控制檯輸出:

學生姓名:
,學生id:
;
2014556698
AgentKyle

需要注意標籤函式第一個引數陣列的最後一個元素,它始終表示最後一個變數到模板字串末尾的部分,在上面的例子中,這部分有一個;(分號)。但如果這部分什麼也沒有,模板就結束了,則其最後一個元素將會是''(空)。模板標籤表示式的最終返回值即標籤函式的返回值。

下面的標籤函式可以返回像不使用模板標籤那樣的填充模板:

function tagFun() {

    let str = '',
        strArr = arguments[0];

    for(let i = 0; i<strArr.length; i++){
        str+=strArr[i];
        str+=arguments[i+1]||''
    }

    return str;
}

引入標籤模板的一個目的在於對模板字串本身進行更靈活的控制,例如去除容易引起安全問題的危險字元,對模板字元進行國際化等等。

此外,你可以使用模板標籤在JS語言中嵌入其他語言:

jsx`
<input ref="input" onchange=${this.handleChange} >
`

上面通過jsx函式將一個DOM字串轉成了React物件。你可以在github上找到jsx函式的原始碼。

此外,標籤函式的第一個引數還具有一個row屬性,它是一個和其宿主陣列幾乎一模一樣的陣列,唯一的區別在於其中的字串元素的反斜線都被轉譯(前面加了一個\)了。String構造器也原生提供了String.row靜態方法,用來生成一個反斜線都被轉譯的字串:

String.row`hello world\n${1+1}` // => hello world\\n2
String.row'\u000A!' // => \\u000A 

4.2 字串的擴充套件方法

includes,startsWith,endsWith

ES5中,當我們試著判斷一個字串片段是否包含在另一個字串時,一般會考慮使用IndexOf的方式:

"But those who wait for the Lord will renew their strength".indexOf('shall') // =>-1

當其匹配成功時,會返回匹配到的位置。若是不存在,則會返回-1。這固然很好,但問題是有的時候我們只不過是想知道A串是否包含在B串內,並不想知道它在哪裡。而且匹配失敗時返回-1的特性無形中增加了編碼量以及出錯的概率:

var flag = "But those who wait for the Lord will renew their strength".indexOf('shall') 
if(flag === -1){}
if(flag){} // 容易出錯的邏輯,這樣其實是指的從字串首匹配成功就不執行裡面的程式碼片段

ES6中提供了三中新方法:

  1. includes() :返回布林值,表示是否找到了字串
  2. startsWith():返回布林值,表示引數字串是否在源字串的開頭
  3. endsWith():返回布林值,表示引數字串是否在源字串的尾部

它們都可以接受第二個引數以控制查詢的範圍,但endsWith與其它的方法行為不同,其它兩個方法都是從規定的索引一直到字串最後進行匹配,而endsWith則是從字串的開頭到規定的索引的中間段進行查詢。下面是一些例子:

let str = "But those who wait for the Lord will renew their strength";
console.log(str.includes('will')); //t
console.log(str.includes('will',40)); //f
console.log(str.startsWith('But'));//t
console.log(str.startsWith('but')); //f 匹配區分大小寫
console.log(str.startsWith('those',4)); // t 注意這裡是4,而並非5,因為包含開頭索引的位置
console.log(str.endsWith('those')); // f
console.log(str.endsWith('those',9)); // t 注意這裡是9,而不是8,因為不包含最後索引的位置

注意,所有的索引都是隻包含開頭索引的位置,不包含結束索引的位置

repeat

有時我們想將一個字串複製累加n次:

let str = 'hello';
let repeatedStr = function (n) {
    let newStr = '';
    for (let i = 0; n < 5; i++) {
        newStr+=str;
    }
    return newStr;
}(5);
console.log(repeatedStr);

ES6提供了原生的解決方案:

let repeatedStr = str.repeat(5);

它接收一個數值型引數,如果傳入一個小數,則會向下取整;0到-1之間的小數,取整後等價於-0,即0;如果傳入一個字串型別的數,則會先轉換成數值型別再進行計算。引數NaN等價於0。

如果其引數是非0到-1之間負數或Infinity,則會報錯。

4.3 字元的Unicode表示法

JS內部,字元以UTF-16的格式儲存,一般而言每個字元固定為2個位元組。同時,JS允許使用\uxxxx形式來表示一個字元,其中xxxx表示碼點。比如:

    console.log('\u0061') //=> a
    console.log('\u0061'==='a');

但是這種表示法只限於\u0000-\uFFFF之間的字元。超出這個範圍的字元,必須用兩個雙位元組形式表達。比如:‘��’字,它對應的碼點表示是:\uD842\uFB7

在ES6中,可以在\u後直接後面跟上超過0xFFF的數值,只要將碼點至於大括號中:

\u{20BB7} \\=>��

但是,這些需要字元實際上需要四個位元組,於是會引起ES5中一些方法的錯誤。比如下面的例子:

var c = '��c'
c.length // =>2
c.charAt(0) // =>''
c.charAt(1) // =>'' 因為字元是四位元組而解析錯誤
c.charAt(2) // =>c
c.charCodeAt(0) //=>55362
c.charCodeAt(1) //=> 57271

ES6提供了對應的方法來解決這個問題:

// 使用codePointAt取代charCodeAt
c.codePointAt(0) // => 134071 返回整個字元的碼點,預設是十進位制的形式,如果想轉為16禁止,可以使用toString(16)
c.codePointAt(1) // => 57271 返回後一半字元的碼點
c.codePointAt(2) // 97 返回a的碼點,但要注意,方法的引數是2

// 使用at取代charAt
c.at(0) // =>'��' 在ES7中定義的方法

相關推薦

深入ES6 字串

第四章 字串的括展 ES6加強了對Unicode的支援,並且擴充套件了字串物件。本章把重點放在ES6對物件方法的括展上,至於字元Unicode表示法的加強,則不打算詳細展開。本章主要包括: 模板字串與標籤模板 字串括展方法 字元的

小白學Python----字串

一、 字串 <1>python中字串的格式  如下定義的變數a,儲存的是數字型別的值 a = 100  如下定義的變數b,儲存的是字串型別的值 b = “hello xiaobai.cn” 或者 b = ‘hello xiaobai.cn’ 小總結: <2>雙引號

Android開發筆記字串格式化

字串的格式化 博主原來是搞C的,C裡面有sprintf來格式化字串,後來轉到java變傻了,拼接String只會用n個“+”,要麼就是用StringBuilder的append方法,但要是遇上把數字格式化的情況(比如左補0等等),就只能傻乎乎的if else判斷該補幾個0。

深入ES6歷史與簡介

第一章 歷史與簡介 ES6於2015年6月正式釋出,其目標是使JS原因呢可用於編寫大型的應用程式,成為企業級的開發語言。這篇文章主要介紹: 1. ECMAScript的版本歷史 2. 使用babel對ES6程式碼進行轉碼 3. 配合gu

深入ES6 let和const

第二章 let和const ES6提供了let和const兩種新的變數宣告方式,使得在JS中變數的宣告更像java那樣。這章主要包括了一下內容: ES6的塊級作用域 let宣告變數與var的區別 死區 const與物件凍結

React與ES6ES6如何處理React mixins

在使用React.createClass()的時候你也許使用過一個所謂的mixin的東西。使用它,你可以給React元件天劍很多其他的功能。這個概念不止用在React上,也用在很多其他的程式語言或者框架上。 在ES6中不能夠在使用React的mixin機制

從零開始學 Web 之 ES6ES6基礎語法二

一、Promise Promise是一個物件,代表了未來某個將要發生的事件(,這個事件通常是一個非同步操作) 有了Promise物件, 可以將非同步操作以同步的流程表達出來, 避免了層層巢狀的回撥函式(俗稱'回撥地獄')。 ES6的Promise是一個建構函式, 用來生成promise例項。 1、prom

資料結構--字串操作

字串 1.串的定義 串是由零個或多個字元組成的有限序列,一般記為 s=′a1a2…a′ns=′a1a2…an′ 串中任意個連續的字元組成的子序列稱為該串的子串。包含子串的串稱為主串。 串的原子操作(其餘操作可以以下操作組合完成)包含以下5種:

深入解讀ES6系列

來自老曾es6的前言: 哈嘍小夥伴們,愛說‘廢’話的Z又回來了,歡迎來到Super IT曾的部落格時間,上一節說了字串,面向物件以及json的知識,這一節我們繼續我們知識的海洋,一起奮鬥不禿頭!不足的歡迎提問留言。 我發誓我真的沒有P圖

shiro的源碼學習-- 深入理解realm

instance his face 成功 返回 void exce gen 調用 IniRealm的類結構如下圖: 下面分析每個類: (1)Ream: 域的頂點,其代碼如下:securityManager會使驗證器來調用,驗證器通過Realm返回用戶信息,確定用戶是否登錄

聊聊高並發二十解析java.util.concurrent各個組件 深入理解AQS

sar 成功 通知 ati help write ng- ads 同步 近期總體過了下AQS的結構。也在網上看了一些講AQS的文章,大部分的文章都是泛泛而談。又一次看了下AQS的代碼,把一些新的要點拿出來說一說。 AQS是一個管程。提供了一個主要的同步器的

深入理解 JavaScript

div 參數 面向 描述 pla 耦合 理論 spl 什麽 前言 Bob 大叔提出並發揚了 S.O.L.I.D 五大原則,用來更好地進行面向對象編程,五大原則分別是: The Single Responsibility Principle(單一職責 SRP) The Op

深入理解JMMJava內存模型 --volatile

iter() 通過 我們 body writer 其它 pen barrier 如何實現 volatile的特性 當我們聲明共享變量為volatile後,對這個變量的讀/寫將會很特別。理解volatile特性的一個好方法是:把對volatile變量的單個讀/寫,看成是使

ES6學習筆記—— async 函數

ons fst cte code span pre getname 普通 聲明 await 是 async wait 的簡寫, 是 generator 函數的語法糖。 async 函數的特點: async 聲明一個方法是異步的,await 則等待這個異步方法執行的完

ES6新特性使用小結

aso 數據 定義 mon 過濾 != style nbsp com 十一、Proxy 、Reflect    ①、Proxy 的概念和常用方法 { let obj = { //1、定義原始數據對象

深入理解Java內存模型——volatile

繼續 表現 可能 class 之前 art 其他 reader int 本文轉自:http://www.infoq.com/cn/articles/java-memory-model-4 volatile的特性 當我們聲明共享變量為volatile後,對這個變量的讀/寫將會

從零開始學 Web 之 ES6ES6基礎語法

實現 fine 開始 isf 原理 mat 系列教程 include number 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之巔

NOIP複賽複習字串演算法鞏固與提高

一、Trie樹   1.定義: 通過字串建成一棵樹,這棵樹的節點個數一定是最少的。例如:4個字串"ab","abc","bd","dda"對應的trie樹如下: 其中紅色節點表示存在一個字串是以這個點結尾的。  一個性質:在樹上,兩個點u,

vue步步深入專案編寫,路由配置

1.在App.vue頁面寫需要的元件 <template> <div id="app"><!--這個到時候會替換掉index.html的#app的DOM元素--> <m-header></m-header> <tab&

深入理解多執行緒—— Moniter的實現原理

在深入理解多執行緒(一)——Synchronized的實現原理中介紹過關於Synchronize的實現原理,無論是同步方法還是同步程式碼塊,無論是ACC_SYNCHRONIZED還是monitorenter、monitorexit都是基於Monitor實現的,那麼這篇來介紹下什麼是Monitor。