0%

JS特訓-DAY36-ES6 Template String 樣板字串

前言

進入 ES6 學習,字串相加語法可以用 Template String 樣板字串

樣板字串

ES6 引入了一種新型的字串語法,稱為「樣板字串(template strings)」。
它可以「放入 HTML 的內容」、「多行字串包含換行」、「字串中插入變數」或 「JavaScript 表達式」。


基本應用

語法是用兩個反引號 `` 標示,舉例來說,如果我們會在 JS 的字串中放入 HTML 內容。

以前寫法:

let component_es5 = '<header>\n'+
'<div class="banner">\n'+
'<img src="img1.jpg"\n'+
'</div>\n'+
'</header>'

用 ES6 寫法可以改為:

let component_es6 = `
<header>
    <div class='banner'>
        <img src="img1.jpg>
    </div>
</header>
`

也就是說,透過反引號包住的內容,會保留所有的換行和空行。


字串中嵌入變數

我們可以透過 ${ } 這樣的方式,嵌入變量或任何的表達式:


let myName = "Bob",
    numA = 2,
    numB = 8;

let content = `Hello, my name is ${myName}, my lucky number is ${3*(numA + numB)}`;

console.log(content);  // "Hello, my name is Bob, my lucky number is 30"

透過 ${ },裡面我們不只可以放入變數,還可以放入表達式(例如${4+5})。


跳脫字元

如果在模版字符串中我們又會使用到反引號的話,這時候我們必須使用跳脫字元 \ 來處理,像是這樣:

var greeting = `\`Hello\` World!`;

console.log(greeting); // "`Hello` World!"

如果要計算字元數,或是需要將字串做額外處理,跳脫字元是不佔字符數的:

console.log(`\\`.length); // 1

要取得含特殊字元的字串可用 String.raw( )

console.log(String.raw`\\`.length)

${ } 內使用函式

可以在 ${} 內使用函式 (函式內可在使用 Template String)。
不過這裡特別注意,單行的箭頭函式會自動 return,所以在這裡是省略了 return。

const people = [
  {
    name: 'Bob',
    age: 19
  },
  {
    name: 'Linda',
    age: 50
  },
  {
    name: 'Jin',
    age: 0
  }
]

let call = `
  <ul>
    ${people.map(person => `<li>我叫做 ${person.name}</li>`).join('')}
  </ul>
`

也可以在函式內增添更多的判斷式

let call = `
  <ul>
    ${people.map((person) => {
        if (person.age) {
          return `<li>${person.name} 今年 ${person.age} 歲</li>`
        } else {
          return `<li>${person.name} 最小</li>`
        }
      }).join('')
    }
  </ul>
`

巢狀 String Template

如同上述的方法 ${ } 內可以加入函式及其更內層的 Template String,所以也可以在 ${ } 插入另一組的函式的 Template String

const travelers = {
  leader: '老媽',
  partner: people
}

function renderList(people) {
  return `
    <div>上車名單</div>
    <ul>
      ${people.map(person => `<li>${person.name}</li>`).join('')}
    </ul>
  `
}

let template = `
  <div class="template">
  <h2>導遊:${travelers.leader}</h2>
  ${renderList(travelers.partner)}
  </div>
`

// "
//   <div class="template">
//   <h2>導遊:老媽</h2>

//     <div>上車名單</div>
//     <ul>
//       <li>Bob</li><li>Linda</li><li>Jin</li>
//     </ul>

//   </div>
// "

示範

以第20關的 BMI 計算機為範例,嘗試改寫。這邊僅附上調整樣板字串的寫法前後對應,其他的部分會在最後附上 CodePen 完整程式碼。

原本的寫法:

function render(){
  let str ='';
  arrayBMIhistory.forEach(function(item){
    return  str +='<li><p class="status-value ' + BMIData[item.status].class+ '">' + BMIData[item.status].statusText +
    '</p><div class="c-list">BMI<span class="bmi-value">' + item.BMI +
    '</span></div><div class="c-list">height:<span class="height-value">'
    + item.height + '<sapn>cm</sapn></span></div><div class="c-list">weight:<span class="weight-value">'
    + item.weight + '<span>kg</span></span></div></li>'
  })  

  listHistory.innerHTML = str;
}

ES6寫法:

function render(){
  let str ='';
  arrayBMIhistory.forEach(function(item){
    return  str +=`<li>
          <p class="status-value"${BMIData[item.status].class}>${BMIData[item.status].statusText}</p>
          <div class="c-list">BMI<span class="bmi-value">${item.BMI}</span></div>
          <div class="c-list">height:<span class="height-value">${item.height}<sapn>cm</sapn></span></div>
          <div class="c-list">weight:<span class="weight-value">${item.weight}<span>kg</span></span></div>
    </li>`
  })

  listHistory.innerHTML = str;
}

CodePen