ES6之-字符串的新特性

ES6對字符串新增了一些函數和操作規範,使得開發者對字符串的操作更加方便,以往需要藉助其他javascript代碼才能實現的效果,現在利用這些函數即可快速實現。

一. 模版字符串

“模板字符串”是字符串的一個新特性,傳統的字符串實現拼接的時候,要將變量插入字符串中,語法是這樣的:

var name = "王永傑";
var age = 25;
//傳統字符串拼接
var str = "我的名字叫:" + a + ",今年" + b + "歲;" ;
console.log(str)

上面變量 str 代碼實現將變量 name 和 age 插入字符串中,這種寫法沒什麼不好,只是數據一旦多起來就很繁瑣,你會看到N多個加號“+”,N多個引號’ “” ‘,ES6給了我們另一種更簡捷的寫法,來看一下下面這段小代碼:

var name = "王永傑"
var age = 25;
//模板字符串拼接
var str = `我的名字叫:${name},今年${age}歲;`
console.log(str)

對比兩段拼接的代碼,模板字符串使得我們不再需要反覆使用雙引號(或者單引號)了;而是改用反引號標識符(`),插入變量的時候也不需要再使用加號(+)了,而是把變量放入${ }即可。

以上就是模板字符串的用法,下面來介紹使用時要注意的地方:
1、可以定義多行字符串

傳統的多行字符串寫法:

var str = "張三 ," +
          "李四";
console.log(str)

模板字符串的寫法:

var str = `張三 ,
           李四`;
console.log(str)

直接換行即可,但是要注意的是:所有的空格和縮進都會被保留在輸出中。如果控制檯輸出字符串str的話,代碼上換了行,控制檯輸出的時候也會換行。

2、${ }中可以放任意的javascript表達式

${ }中可以是運算表達式

var a = 1;
var b = 2;
var str = `a +b 的和爲${a+b}`;
//進行加法運算
console.log(str)  //a +b 的和爲3

${ }中可以是對象的屬性

var obj = {
    "a":1,
    "b":2
}
//對象obj的屬性
var str = `a + b 的和爲${obj.a+obj.b}`
console.log(str)  //a + b 的和爲3

${ }中可以是函數的調用

function add(){
    return 3
}
 //函數fn的調用
var str = `${add()}`
console.log(str)  //3

二、標籤模板

這裏的模板指的是上面講的字符串模板,用反引號定義的字符串;而標籤,則指的是一個函數,一個專門處理模板字符串的函數,如下代碼:

var name = "張三";
var height  = 1.8;

tagFn`他叫${name},身高${height}米。`;
//標籤+模板字符串

//定義一個函數,作爲標籤
function tagFn(arr,v1,v2){
    console.log(arr); 
    //結果:[ "他叫",",身高","米。" ]
    console.log(v1); 
    //結果:張三
    console.log(v2); 
    //結果:1.8
}

以上代碼有兩處要仔細講解的,首先是tagFn函數,是我們自定義的一個函數,它有三個參數分別是arr,v1,v2。函數tagFn的調用方式跟以往的不太一樣,以往我們使用括號( )表示函數調用執行,這一次我們在函數名後面直接加上一個模板字符串,如下面的代碼:

tagFn`他叫${name},身高${height}米。`;
  • 這樣就是標籤模板,你可以理解爲標籤函數+模板字符串,這是一種新的語法規範。
  • 接下來我們繼續看函數的3個參數,從代碼的打印結果我們看到它們運行後對應的結果,arr的值是一個數組:[ “他叫” , “,身高” , “米。” ],而v1的值是變量name的值:“張三”,v2的值是變量height的值:1.8。
  • 你是否看出規律了:第一個參數arr是數組類型,它的內容是模板字符串中除了${ }以外的其他字符,按順序組成了數組的內容,所以arr的值是[ “他叫”, “,身高” , “米。” ];第2,3個參數則是模板字符串中對應次序的變量name和height的值。
  • 標籤模板是ES6給我們帶來的一種新語法,它常用來實現過濾用戶的非法輸入和多語言轉換,這裏不展開講解。因爲一旦我們掌握了標籤模板的用法後,以後就可以好好利用它的這個特性,再根據自己的需求要來實現各種功能了。

三、repeat(重複)函數

repeat( )函數:將目標字符串重複N次,返回一個新的字符串,不影響目標字符串。

var name1 = "王永傑";              //目標字符串
var name2 =  name1.repeat(3);   //變量name1被重複三次;
console.log(name1);             //結果:王永傑
console.log(name2);             //結果:王永傑王永傑王永傑

重複3次後返回一個新字符串賦值給name2,name1不受影響,所以name1的值不變。

四、includes(包含)函數

includes( )函數:判斷字符串中是否含有指定的子字符串,返回true表示含有和false表示未含有。第二個參數選填,表示開始搜索的位置。

var name = "王永傑";    //目標字符串
var arr1 = name.includes('永');   
console.log(arr1)       //true, 含有

var arr2 = name.includes('男');  
console.log(arr2)       //false, 不含有

var arr3 = name.includes('王',1); 
console.log(arr3)       //false, 從第2個字符開始搜索, 不含有

傳統的做法我們可以藉助indexOf( )函數來實現,如果含有指定的字符串,indexOf( )函數就會子字符串首次出現的位置,不含有,則返回-1。我們通過返回值是否爲-1來判斷字符串中是否含有指定的子字符串,但是,我們現在可以用includes( )函數代替indexOf( )函數,因爲它的返回值更直觀(true或false),況且我們並不關心子字符串出現的位置。

* 注意*:上面 arr3 代碼,第二個參數爲1,表示從第2個字符“永“開始搜索,第一個字符”前“的位置是0,類似於數組的下標;

五、startsWith(從…開始)函數

startsWith( )函數:判斷指定的子字符串是否出現在目標字符串的開頭位置,第二個參數選填,表示開始搜索的位置。

var name = "王永傑";  //目標字符串
var str1 = name.startsWith('王');        //true,出現在開頭位置
console.log(str1)

var str2 = name.startsWith('永');        //false,不是在開頭位置
console.log(str2)

var str3 = name.startsWith('永',1);  //true,從第2個字符開始
console.log(str3)

我們如果判斷字符串是否以某個子字符串開頭,就可以直接使用startsWith( )函數即可,同樣,第二個參數爲1表示從第2個字符開始搜索。若要從第一個字符開始搜索,參數應該爲0或者爲空(默認從第一個字符開始搜索)。

六、endsWith(在…結束)函數

endsWith( )函數:判斷子字符串是否出現在目標字符串的尾部位置,第二個參數選填,表示針對前N個字符。

var name = "我就是王永傑";            //目標字符串
var str1 = name.endsWith('我');      //false,不在尾部位置
console.log(str1)

var str2 = name.endsWith('傑');  //true,在尾部位置
console.log(str2)

var str3 = name.endsWith('傑',5);    //false,只針對前5個字符
console.log(str3)

var str4 = name.endsWith('傑',6);    //true,針對前6個字符
console.log(str4)

七、codePointAt()函數 參考解釋

javascript中,一個字符固定爲2個字節,對於那些需要4個字節存儲的字符,javascript會認爲它是兩個字符,此時它的字符長度length爲2。如字符:”��”,就是一個需要4個字節存儲,length爲2的字符。這會有什麼問題呢?對於4字節的字符, javascript無法正確讀取字符,我們來試試看。

var str1 = "永傑";
var str2 = "��";

console.log(str1.length); //length爲2
console.log(str2.length); //length爲2

console.log(str1.charAt(0));  //永
console.log(str1.charAt(1));  //傑

console.log(str2.charAt(0));  //'�'
console.log(str2.charAt(1));  //'�'

由於這裏寫圖片描述這個文字在圖片描述存在亂碼問題,所以使用圖片說明一下:
這裏寫圖片描述
- 可以看到,str1和str2的長度length都是2,因爲字符:”��”是一個4字節的字符,使用charAt函數(charAt() 方法可返回指定位置的字符)能正確讀取字符串str1的字符,但無法正確讀取4個字節的字符,此時返回結果出現了亂碼。
- 但是,如果我們使用ES6給我們提供的codePointAt( )函數(codePointAt( )方法可以正確地識別出它是個4個字節的字符,並且能正確地返回它的碼點的十進制數),就可以處理這種4個字節的字符了,我們來看看怎麼使用:

var str = "��";
console.log(str.codePointAt());  //結果:134071
  • 對於這個長度length爲2字符:”��”,codePointAt( )方法可以正確地識別出它是個4個字節的字符,並且能正確地返回它的碼點的十進制數:134071,這個數字抓換成16進制就是20bb7,對應的Unicode編碼則是\u20bb7。(什麼是Unicode編碼?稍後講解)。

  • 什麼?十進制的數字134071就是對應4個字節的字符:”��”了?能不能驗證一下?通過134071這個數字反推回去,得到字符:”��”?

  • 可以的,ES6還提供了一個函數給我們來實現這個效果。

八、String.fromCodePoint()函數

String.fromCodePoint( )函數:函數的參數是一個字符對應的碼點,返回的結果就是對應的字符,哪怕這個字符是一個4字節的字符,也能正確實現。
正好可以利用上面得到的10進制數字134071反推一下。

String.fromCodePoint(134071); //結果:"��"
  • 得到了我們預期的結果:”��”;同時也證明了上面的codePointAt( )函數能正確讀取4個字節的字符

九、String.raw函數

最後講解的一個函數是String.raw( );看函數名raw是未加工的的意思,正如這個函數的作用一樣:返回字符串最原始的樣貌,即使字符串中含有轉義符,它都視而不見,直接輸出。舉個例子:

未經String.raw( )處理的字符串:
console.log(`hello\nworld`);
//輸出:hello
        world
 \n會被識別爲換行符,實現換行效果,而經過String.raw( )的同一個字符串的結果是:
console.log(String.raw`hello\nwolrd`);
//輸出:hello\nwolrd
  • \n被識別爲\和n兩個字符,失去換行的效果,直接輸出,這就是String.raw( )的功能。它常用來作爲一個模板字符串的處理函數,也就是直接在後面加一個模板字符串。

補充:Unicode編碼

  • 上面講解codePointAt()函數的時候提到Unicode編碼,對於初學者也許還是很理解,在這裏擴展一下,我們先看看維基百科的解釋:

    Unicode(中文:萬國碼、國際碼、統一碼、單一碼)是計算機科學領域裏的一項業界標準。它對世界上大部分的文字系統進行了整理、編碼,使得電腦可以用更爲簡單的方式來呈現和處理文字。

  • 想想,爲什麼有時候收到的郵件會出現亂碼?就是因爲發郵件的人可能用日文的編碼體系,而收郵件的人用的是中文體系,他們對同一個二進制編碼值進行顯示,採用了不同的編碼,導致亂碼。這個問題促使了unicode碼的誕生。

    • 好比小強給外國的朋友Peter發了一句:66666,表達很溜很牛的意思。
    • 但是Peter對這個詞的認知不一樣(編碼體系不一樣),無法get到小強想表達的意思,表示很疑惑(出現亂碼)。
    • 最後大家約定,用一種大家都看得懂的方式交流(統一一種編碼體系:unicode碼),大家都遵守這種交流方式,就能愉快的玩耍了(不會出現亂碼,郵件內容正常顯示)。

總結:ES6給字符串帶來了很多實用性的擴展:模板字符串,標籤模板,repeat函數、includes函數,startsWith函數,endsWith函數,codePointAt函數,String.fromCodePoint函數,String.raw函數。還順帶學習了一些關於Unicode編碼的知識。


說明:部分內容參考網絡

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