ES6的全新特性:模板字串

flowerwxc發表於2015-12-09

作為JavaScript的未來,ES6已經到來。作為已完成的標準,ES6帶來了許多新特性使其在如今的web世界仍有競爭力。ES6的方方面面不一定全都適合你,本文集會簡要介紹一些順手且可行的新特性。

我編寫JavaScript程式碼更喜歡使用單引號來定義字串,而不是雙引號。對JavaScript來說兩者都可以,下面的兩行程式碼其實作用相同:

1.var animal = "cow";

2.var animal = 'cow';

我更喜歡單引號是有原因的。首先,單引號在組合使用HTML字串和引用屬性時更加方便。

1.// with single quotes, there's no need to

  1. // escape the quotes around the class value

3.var but = 'Save';

4.// this is a syntax error:

  1. var but = "Save";

6.// this works:

7.var but = "Save";

只有在 HTML 中使用單引號之時才需要轉義,而HTML中是極少使用單引號的。我能想到的場景無非是內聯 JavaScript 或 CSS,也就是說此時寫的東西是靠不住的或者極度依賴標記語言。而在正文中,還不如使用排版更悅目的而不是單引號'。[^注: 也就是說不用轉義了。]

旁註: 當然,HTML相當寬容,你大可以刪除引號或者轉而使用單引號來包裹屬性,但是我寧願寫可讀性更好的標記語言而不是過分依賴語法分析程式。如今的HTML5語法分析程式如此寬容是因為過去人們寫的標記語言太糟糕了,這不是繼續糟糕下去的藉口。

在 DHTML 時代在框架集內部使用 document.writer 在新彈出視窗上建立文件之類的令人噁心的事情我已經受夠了。我再也不要使用轉義字元了。我甚至有時候還會用到三引號,這還是在編輯器有彩色高亮之前的事。簡直是一團糟。

在字串中使用變數替換

我更喜歡單引號還有一個原因。在編寫高效能要求的網站時候我會大量使用PHP,而PHP是區分單引號和雙引號的。PHP的單引號不允許字串內變數替換,而雙引號允許。

也就是說在 PHP 3 和 PHP 4 時代使用單引號的效率更高,因為語法分析程式省去了檢索整個字串進行變數替換的麻煩。看下面的例子你就明白了:

1.

  1. $sound = 'moo';

  2. echo 'The animal is $animal and its sound is $sound';

  3. // => The animal is $animal and its sound is $sound

  4. echo "The animal is $animal and its sound is $sound";

  5. // => The animal is cow and its sound is moo

7.?>

JavaScript不支援字串內的變數替換,所以不得不使用拼接字串來代替。這顯然太麻煩了,不得不頻繁地在引文內和引文外來回切換。

1.var animal = 'cow';

2.var sound = 'moo';

3.alert('The animal is ' + animal + ' and its sound is ' +

  1. sound);

5.// => "The animal is cow and its sound is moo"

多行字串的麻煩

在處理越來越長的字串,尤其是組合使用大量 HTML 的時候真的是麻煩異常。而且很可能到頭來 Linting 工具會報錯說行末的 + 後面有個多於的空格。這問題完全是因為JavaScript不支援多行字串。

1.// 這樣寫是不行的:

  1. var list = '

    • Buy Milk
    • Be kind to Pandas
    • Forget about Dre

    6.';

    7.// 可以這樣寫,但是,呃

    1. var list = '

        \
    2. Buy Milk
    3. \
    4. Be kind to Pandas
    5. \
    6. Forget about Dre
    7. \
    8. ';

    13.// 這是最常見的寫法,但是,呃

    1. var list = '

        ' +
    2. '

    3. Buy Milk
    4. ' +
    5. '

    6. Be kind to Pandas
    7. ' +
    8. '

    9. Forget about Dre
    10. ' +

    18.'';

    客戶端的模板解決方法

    為了在搞定麻煩的JavaScript字串處理和拼接問題,還是得走到老路上,寫個庫。現有的眾多HTML模板庫中,Mustache.js 大概是影響力最大的。這些庫大都遵循自定的非標準語法,使用起來完全看心情。打個比方,這就像是你用markdown格式寫東西,然後意識到”markdown”本身就有很多不同的意思。[注:markdown有眾多風格]

    使用模板字串

    隨著ES6及其標準的到來,我們欣喜地發現使用JavaScript處理字串時可以使用模板字串了。現在主流瀏覽器對模板字串的支援非常及時:Chrome 44+, Firefox 38+, Microsoft Edge 和 Webkit 全部支援。遺憾的是 Safari 尚未支援,但是也不會等很久。

    模板字串的設計天才之處在於使用了全新的字串限定符,即在HTML和尋常文字中皆不常見的反引號(`)。

    1.var animal = 'cow';

    2.var sound = 'moo';

    1. 4.alert(The animal is ${animal} and its sound is ${sound});

    5.// => "The animal is cow and its sound is moo"

    ${} 接受任意的 JavaScript 表示式並返回相應值,可以用來進行數學運算或者訪問物件的屬性等等。

    1.var out = ten times two totally is ${ 10 * 2 };

    2.// => "ten times two totally is 20"

    3.var animal = {

    1. name: 'cow',

    2. ilk: 'bovine',

    3. front: 'moo',

    4. back: 'milk',

    5. }

    6. alert(`

    7. The ${animal.name} is of the

    8. ${animal.ilk} ilk,

    9. one end is for the ${animal.front},

    10. the other for the ${animal.back}

    11. `);

    12. // =>

    13. /*

    14. The cow is of the

    15. bovine ilk,

    16. one end is for the moo,

    17. the other for the milk

    21.*/

    第二個例子表明多行字串再也不是個問題啦。

    標籤化的模板

    還可以在模板字串之前加上一個標籤,用作函式名,可以呼叫這個函式而字串就是引數。下面的例子實現了對返回的字串進行編碼生成URL,避免總是使用不友好的 namedencodeURIComponent。

    1.function urlify (str) {

    1. return encodeURIComponent(str);

    3.}

    4.urlify http://beedogs.com;

    1. // => "http%3A%2F%2Fbeedogs.com"

    2. urlify woah$£$%£^$";

    3. // => "woah%24%C2%A3%24%25%C2%A3%5E%24%22"

    8.// nesting also works:

    9.var str = foo ${urlify&&} bar;

    10.// => "foo %26%26 bar"

    這樣是能用是能用,卻依賴於隱式的陣列到字串的強制轉換。傳遞給函式的元素並不是字串,而是字串和值構成的陣列。如果像上面這樣使用,為了方便會被自動轉換成字串,但是正確的方法是直接訪問陣列成員。

    在模板字串中檢索字串和值

    在標籤函式內部,不僅可以使用完整字串,還可以只使用字串的一部分。

    1.function tag (strings, values) {

    1. console.log(strings);

    2. console.log(values);

    3. console.log(strings1);

    5.}

    6.tag you ${3+4} it;

    7./* =>

    1. 9.Array [ "you ", " it" ]

    10.7

    11.it

    12.*/

    你還可以使用原始字串的陣列,這意味著可以獲取字串中的所有字元,這裡說的「所有」是指包括控制字元[^注:非列印字元]。比如在新增換行時使用的 \n 就是控制字元。在字串中只能得到兩個空格,而在原始字串中可以取得 \n 字元。

    1.function tag (strings, values) {

    1. console.log(strings);

    2. console.log(values);

    3. console.log(strings1);

    4. console.log(string.raw1);

    6.}

    7.tag you ${3+4} \nit;

    8./* =>

    9.Array [ "you ", " it" ]

    10.7

    11.it

    1. \nit

    13.*/

    結論

    模板字串是ES6引入的超讚小特性,現在就可以使用。如果需要支援更老舊的瀏覽器,當然還可以把 ES6 轉換編譯 [注:transpile] 回 ES5。還可以針對模板字串做一下特性檢測,使用諸如 featuretests.io 的庫,或者用下面的程式碼:

    1.var templatestrings = false;

    2.try {

    1. new Function( "{2+2}" );

    2. templatestrings = true;

    5.} catch (err) {

    1. templatestrings = false;

    7.}

    8.if (templatestrings) {

    1. // …

    10.}

    原文連結:http://www.gbtags.com/gb/share/9579.htm

    相關文章