ES6學習筆記之字符串的擴展

字符串的擴展

幾個用於字符串處理的函數

字符串查詢

  • indexOf() 返回數字,表示參數在字符串中的位置,如沒有,就返回-1。
  • includes() 返回布爾值,表示是否找到了參數字符串。
  • startsWith() 返回布爾值,表示參數字符串是否在原字符串的頭部。
  • endsWith() 返回布爾值,表示參數字符串是否在原字符串的尾部。
let str = 'abcdefg'

str.indexOf('c') //2 
str.indexOf('x') // -1
str.indexOf('a', 1) // -1
str.indexOf('c', 1) // 2


str.includes('a')   // true
str.includes('a', 1)  // false
str.includes('c', 1)  // true


str.startsWith('a')  // true
str.startsWith('b')  // false
str.startsWith('b', 1) // true
str.startsWith('a', 1) // false


str.endsWith('g')     // true
str.endsWith('f')     // false
str.endsWith('g', 3)   // false
str.endsWith('c', 3)  // true


複製代碼

repeat()

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

'ab'.repeat(3) // "ababab"
'ab'.repeat(0) // ""

複製代碼

padStart(),padEnd()

ES2017 引入了字符串補全長度的功能。若是某個字符串不夠指定長度,會在頭部或尾部補全。padStart()用於頭部補全,padEnd()用於尾部補全。 padStartpadEnd 有兩個參數數組

第一個參數:用來指定字符串的最小長度
第二個參數:是用來補全的字符串的bash

'abc'.padStart(5, 'x')  // xxabc
'abc'.padEnd(5, 'x')    // abcxx

複製代碼
  1. 若是原字符串的長度,等於或大於指定的最小長度,則返回原字符串。
  2. 若是用來補全的字符串與原字符串,二者的長度之和超過了指定的最小長度,則會截去超出位數的補全字符串。
  3. 若是省略第二個參數,默認使用空格補全長度。
'abc'.padStart(2, 'x')  //  abc
'abc'.padEnd(2, 'x')    //  abc

'abc'.padStart(10, '0123456789')  // '0123456abc'

'x'.padStart(4) // ' x'
'x'.padEnd(4) // 'x '

複製代碼

應用函數

//  爲數值補全指定位數。
'1'.padStart(10, '0') // "0000000001"

//  提示字符串格式
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"

複製代碼

模板字符串

字符串不使用引號括起來,而使用反引號(``)括起來。ui

基本用法:

// 普通字符串
`this is a str`

// 多行字符串
`this is a 
multi-line. sentence`

// 字符串中嵌入變量
var name = "Li", age = 10;
`i'm ${name}, I'm ${age + 1} years old`
複製代碼

有如下特色:this

  1. 能夠當普通字符串用。普通字符串有的功能模板字符串都有。
  2. 能夠用來定義多行字符串而無需寫換行符,只要原樣輸入便可。全部的空格和縮進都會被保留在輸出之中。
  3. 能夠嵌入變量,表達式。(另外一個模板字符串也是變量,因此模板字符串是能夠層層嵌套的)

當前入的變量或表達的結果不是字符串時會自動轉換成字符串:spa

// undefined
`echo ${undefined} !` // 'echo undefined !'

// null 
`echo ${null}` // 'echo null !'

// object
let obj = { a: 1 }
`echo ${obj} !` // 'echo [object Object] !'

// array
let arr = ['a', 'b']
`echo ${arr} !` // 'echo a,b !'

//number
let num = 123
`echo ${num} !` // 'echo 123 !'
複製代碼

標籤模板

模板字符串能夠緊跟在函數後,讓函數來處理這個字符串。這被稱爲「標籤模板」功能(tagged template)。設計

alert`123`
// 等同於
alert(123)
複製代碼

標籤模板是函數調用的一種特殊形式。「標籤」指的就是函數,緊跟在後面的模板字符串就是它的參數。
若是模板字符裏面有變量,會將模板字符串先處理成多個參數,再調用函數。code

let xx = '你好'
console.log`Hello ${xx} world ${ 10 } !`

console.log(['Hello', 'world', '!'], xx, 10)
複製代碼

模板字符串 會以變量或表達式爲分隔符分割。htm

  • 字符串部分變爲一個數組,
  • 變量部分變爲多個變量,成爲參數 生成的數組會擁有一個 raw 屬性,raw 的值 就是該數值成員的轉義後的 組成的數組。
const fun = (arr1, ...arr2) => {
  console.log(arr1)
  console.log(arr2)
}

const fun = (arr1, param1, param2, param3....) => {
  ...
}

fun`this ${'sentence'} \n is ${'xxx'}`
複製代碼

這是爲了方便取得轉義以前的原始模板而設計的。

模板標籤的應用:
1. 重組字符串,過濾 HTML 字符串,防止用戶輸入惡意內容。

function SaferHTML(strs, ...pars) {
  let str = strs[0]
  for (let i = 1; i < strs.length; i++) {
    let param = String(pars[i - 1])
    str += param.replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
    str += strs[i]
  }
  return str;
}

let name = 'Tim'
let message = "<script> alert('x') </script>"

SaferHTML`@${name} said: ${message}`
複製代碼

2. 多語言轉換

const i18n = (strs, ...pars) => {
  return  `歡迎訪問${pars[0]},您是第${pars[1]}位訪問者!`
}


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

3. 使用標籤模板,在 JavaScript 語言之中嵌入其餘語言。

jsx`
  <div>
    <input
      ref='input'
      onChange='${this.handleChange}'
      defaultValue='${this.state.value}' />
      ${this.state.value}
   </div>
`

複製代碼

上面的代碼經過jsx函數,將一個 DOM 字符串轉爲 React 對象。

String.raw()

String.raw方法,返回一個被轉義的字符串。

String.raw`Hi\n${2+3}!`;
// "Hi\\n5!"

String.raw`Hi\u000A!`;
// 'Hi\\u000A!'
複製代碼

若是原字符串的斜槓已經轉義,那麼String.raw不會作任何處理。

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

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

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

模板編譯

模板自身封裝方法

模板字符串能夠經過 new Functioneval.call,將字符串組成的函數語句 轉換成可執行的函數。

// 寫法一
let str = 'return ' + "`Hello ${name}! I'm ${me}`";
let func = new Function('name', 'me', str);
func('Jack', 'Tome') // "Hello Jack!"

// 寫法二
let str = '(name) => `Hello ${name}!`';
let func = eval.call(null, str);
func('Jack') // "Hello Jack!"
複製代碼

模板實例

現有一個數據

const data = ['1模板內容111','2模板內容222','3模板內容333']
複製代碼

如何封裝一個方法以列表的形式將數據展現出來。那就須要封裝一個模板。

1. 首先有一個原始模板

//  指望
<ul>
  <li>1模板內容111</li>
  <li>2模板內容222</li>
  <li>3模板內容333</li>
</ul>


//原始模板
var template = `
<ul>
  <% for(var i=0; i < data.length; i++) { %>
    <li><%= data[i] %></li>
  <% } %>
</ul>`;
複製代碼

2.使用ES5語法的循環拼接字符串,這裏設置一個循環拼接函數爲echo() 將其轉換爲JavaScript表達式字符串

echo('<ul>');
for(var i=0; i < data.length; i++) {
  echo('<li>');
  echo(data[i]);
  echo('</li>');
};
echo('</ul>');

複製代碼

3. 用正則來匹配將基礎字符串模板替換爲想要的字符串模板

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

templateX = template
  .replace(evalExpr, '`); \n echo( $1 ); \n echo(`')
  .replace(expr, '`); \n $1 \n echo(`')

templateX = 'echo(`' + templateX + '`);'
複製代碼

4.將template封裝成一個輸出模板的函數內容的模板字符串。(經過 new Functioneval.call,將字符串組成的函數語句 轉換成可執行的函數。)

var script =
  `(function parse(data){
    var output = "";

    function echo(html){
      output += html;
    }

    ${ templateX }

    return output;
  })`

複製代碼

5. 完整的封裝

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;
}
var parse = eval(compile(template));
let innerHTML = parse(data);


複製代碼
相關文章
相關標籤/搜索