Thứ ba, 30/06/2020 | 00:00 GMT+7

Hiểu các chữ mẫu trong JavaScript

Phiên bản năm 2015 của đặc tả ECMAScript (ES6) đã thêm các ký tự mẫu vào ngôn ngữ JavaScript. Các ký tự mẫu là một hình thức tạo chuỗi mới trong JavaScript bổ sung nhiều khả năng mới mạnh mẽ, chẳng hạn như tạo chuỗi nhiều dòng dễ dàng hơn và sử dụng trình giữ chỗ để nhúng các biểu thức vào một chuỗi. Ngoài ra, một tính năng nâng cao được gọi là các chữ mẫu được gắn thẻ cho phép bạn thực hiện các thao tác trên các biểu thức trong một chuỗi. Tất cả các khả năng này làm tăng các tùy chọn của bạn để thao tác chuỗi với quyền là nhà phát triển, cho phép bạn tạo các chuỗi động được dùng cho các URL hoặc hàm tùy chỉnh các phần tử HTML .

Trong bài viết này, bạn sẽ xem xét sự khác biệt giữa các chuỗi được trích dẫn đơn / kép và các ký tự mẫu, chạy qua các cách khác nhau để khai báo các chuỗi có hình dạng khác nhau, bao gồm chuỗi nhiều dòng và chuỗi động thay đổi tùy thuộc vào giá trị của một biến hoặc biểu thức. Sau đó, bạn sẽ tìm hiểu về các mẫu được gắn thẻ và xem một số ví dụ thực tế về các dự án sử dụng chúng.

Khai báo chuỗi

Phần này sẽ xem xét cách khai báo chuỗi với dấu nháy đơn và dấu nháy kép, sau đó sẽ chỉ cho bạn cách làm tương tự với các ký tự mẫu.

Trong JavaScript, một chuỗi có thể được viết bằng dấu ngoặc kép ( ' ' ):

const single = 'Every day is a good day when you paint.' 

Một chuỗi cũng có thể được viết bằng dấu ngoặc kép ( " " ):

const double = "Be so very light. Be a gentle whisper." 

Không có sự khác biệt lớn trong JavaScript giữa các chuỗi được trích dẫn đơn hoặc kép, không giống như các ngôn ngữ khác có thể cho phép nội suy trong một loại chuỗi nhưng không cho phép loại khác. Trong ngữ cảnh này, nội suy đề cập đến việc đánh giá trình giữ chỗ như một phần động của chuỗi.

Việc sử dụng các chuỗi được trích dẫn đơn hoặc kép chủ yếu phụ thuộc vào sở thích và quy ước cá nhân, nhưng được sử dụng kết hợp, mỗi loại chuỗi chỉ cần thoát khỏi loại trích dẫn riêng của nó:

// Escaping a single quote in a single-quoted string const single = '"We don\'t make mistakes. We just have happy accidents." - Bob Ross'  // Escaping a double quote in a double-quoted string const double = "\"We don't make mistakes. We just have happy accidents.\" - Bob Ross"  console.log(single); console.log(double); 

Kết quả của phương thức log() ở đây sẽ in hai chuỗi giống nhau ra control panel :

Output
"We don't make mistakes. We just have happy accidents." - Bob Ross "We don't make mistakes. We just have happy accidents." - Bob Ross

Mặt khác, các ký tự mẫu được viết bằng cách bao quanh chuỗi bằng ký tự hình que ngược, hoặc dấu nặng ( ` ):

const template = `Find freedom on this canvas.` 

Họ không cần phải thoát khỏi dấu ngoặc kép đơn hoặc kép:

const template = `"We don't make mistakes. We just have happy accidents." - Bob Ross` 

Tuy nhiên, họ vẫn cần phải thoát khỏi backticks:

const template = `Template literals use the \` character.` 

Các ký tự mẫu có thể làm mọi thứ mà các chuỗi thông thường có thể làm được, vì vậy bạn có thể thay thế tất cả các chuỗi trong dự án của bạn bằng chúng và có cùng chức năng. Tuy nhiên, quy ước phổ biến nhất trong cơ sở mã là chỉ sử dụng các ký tự mẫu khi sử dụng các khả năng bổ sung của các ký tự mẫu và sử dụng nhất quán các dấu ngoặc kép đơn hoặc kép cho tất cả các chuỗi đơn giản khác. Tuân theo tiêu chuẩn này sẽ giúp mã của bạn dễ đọc hơn nếu được nhà phát triển khác kiểm tra.

Đến đây bạn đã thấy cách khai báo chuỗi với dấu ngoặc đơn, dấu ngoặc kép và dấu ngoặc kép, bạn có thể chuyển sang lợi thế đầu tiên của chữ mẫu: viết chuỗi nhiều dòng.

Chuỗi nhiều dòng

Trong phần này, trước tiên bạn sẽ chạy qua cách các chuỗi có nhiều dòng được khai báo trước ES6, sau đó xem cách các ký tự mẫu làm cho việc này dễ dàng hơn.

Ban đầu, nếu bạn muốn viết một chuỗi kéo dài nhiều dòng trong editor của bạn , bạn sẽ sử dụng toán tử nối . Tuy nhiên, đây không phải lúc nào cũng là một quá trình thẳng thắn. Việc nối chuỗi sau dường như chạy trên nhiều dòng:

const address =    'Homer J. Simpson' +    '742 Evergreen Terrace' +    'Springfield' 

Điều này có thể cho phép bạn chia chuỗi thành các dòng nhỏ hơn và bao gồm nó trên nhiều dòng trong editor , nhưng nó không ảnh hưởng đến kết quả của chuỗi. Trong trường hợp này, tất cả các chuỗi sẽ nằm trên một dòng và không được phân tách bằng dòng mới hoặc dấu cách. Nếu bạn đăng nhập address vào console , bạn sẽ nhận được những điều sau:

Output
Homer J. Simpson742 Evergreen TerraceSpringfield

Bạn có thể sử dụng ký tự gạch chéo ngược ( \ ) để tiếp tục chuỗi thành nhiều dòng:

const address =   'Homer J. Simpson\   742 Evergreen Terrace\   Springfield' 

Điều này sẽ giữ lại bất kỳ thụt lề nào dưới dạng khoảng trắng, nhưng chuỗi sẽ vẫn nằm trên một dòng trong kết quả :

Output
Homer J. Simpson 742 Evergreen Terrace Springfield

Sử dụng ký tự dòng mới ( \n ), bạn có thể tạo một chuỗi nhiều dòng thực sự:

const address =    'Homer J. Simpson\n' +    '742 Evergreen Terrace\n' +    'Springfield' 

Khi đăng nhập vào console , nó sẽ hiển thị như sau:

Output
Homer J. Simpson 742 Evergreen Terrace Springfield

Tuy nhiên, việc sử dụng các ký tự dòng mới để chỉ định các chuỗi nhiều dòng có thể phản trực giác. Ngược lại, việc tạo một chuỗi nhiều dòng với các ký tự mẫu có thể dễ dàng hơn nhiều. Không cần phải nối, sử dụng ký tự dòng mới hoặc sử dụng dấu gạch chéo ngược. Chỉ cần nhấn ENTER và viết chuỗi trên nhiều dòng theo mặc định:

const address = `Homer J. Simpson 742 Evergreen Terrace Springfield` 

Đầu ra của việc ghi log này vào console giống như đầu vào:

Output
Homer J. Simpson 742 Evergreen Terrace Springfield

Bất kỳ thụt lề nào sẽ được giữ nguyên, vì vậy điều quan trọng là không thụt lề bất kỳ dòng bổ sung nào trong chuỗi nếu điều đó không được mong muốn. Ví dụ, hãy xem xét những điều sau:

const address = `Homer J. Simpson                  742 Evergreen Terrace                  Springfield` 

Mặc dù kiểu viết dòng này có thể làm cho mã dễ đọc hơn, nhưng kết quả kết quả sẽ không phải là:

Output
Homer J. Simpson 742 Evergreen Terrace Springfield

Với các chuỗi nhiều dòng hiện đã được đề cập, phần tiếp theo sẽ giải quyết cách các biểu thức được nội suy thành giá trị của chúng với các khai báo chuỗi khác nhau.

Nội suy biểu thức

Trong các chuỗi trước ES6, phép nối được sử dụng để tạo một chuỗi động với các biến hoặc biểu thức:

const method = 'concatenation' const dynamicString = 'This string is using ' + method + '.' 

Khi đăng nhập vào console , điều này sẽ mang lại kết quả sau:

Output
This string is using concatenation.

Với các ký tự mẫu, một biểu thức có thể được nhúng vào trình giữ chỗ . Một trình giữ chỗ được biểu thị bằng ${} , với bất kỳ thứ gì bên trong dấu ngoặc nhọn được coi là JavaScript và bất kỳ thứ gì bên ngoài dấu ngoặc được coi là một chuỗi:

const method = 'interpolation' const dynamicString = `This string is using ${method}.` 

Khi dynamicString được ghi vào console , console sẽ hiển thị như sau:

Output
This string is using interpolation.

Một ví dụ phổ biến về việc nhúng các giá trị vào một chuỗi có thể là để tạo URL động. Với nối, điều này có thể phức tạp. Ví dụ: phần sau khai báo một hàm để tạo chuỗi truy cập OAuth :

function createOAuthString(host, clientId, scope) {   return host + '/login/oauth/authorize?client_id=' + clientId + '&scope=' + scope }  createOAuthString('https://github.com', 'abc123', 'repo,user') 

Ghi log chức năng này sẽ mang lại URL sau cho console :

Output
https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user

Sử dụng nội suy chuỗi, bạn không còn phải theo dõi việc mở và đóng chuỗi cũng như vị trí của toán tử nối. Đây là ví dụ tương tự với các ký tự mẫu:

function createOAuthString(host, clientId, scope) {   return `${host}/login/oauth/authorize?client_id=${clientId}&scope=${scope}` }  createOAuthString('https://github.com', 'abc123', 'repo,user') 

Điều này sẽ có kết quả giống như ví dụ nối:

Output
https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user

Bạn cũng có thể sử dụng phương thức trim() trên một mẫu chữ để loại bỏ bất kỳ khoảng trắng nào ở đầu hoặc cuối chuỗi. Ví dụ: phần sau sử dụng hàm mũi tên để tạo phần tử HTML <li> với liên kết tùy chỉnh:

const menuItem = (url, link) =>   ` <li>   <a href="${url}">${link}</a> </li> `.trim()  menuItem('https://google.com', 'Google') 

Kết quả sẽ được cắt bỏ tất cả khoảng trắng, đảm bảo phần tử sẽ được hiển thị chính xác:

Output
<li> <a href="https://google.com">Google</a> </li>

Toàn bộ biểu thức có thể được nội suy, không chỉ các biến, chẳng hạn như trong ví dụ về tổng của hai số:

const sum = (x, y) => x + y const x = 5 const y = 100 const string = `The sum of ${x} and ${y} is ${sum(x, y)}.`  console.log(string) 

Đoạn mã này xác định hàm sum và các biến xy , sau đó sử dụng cả hàm và các biến trong một chuỗi. Kết quả đã ghi sẽ hiển thị như sau:

Output
The sum of 5 and 100 is 105.

Điều này có thể đặc biệt hữu ích với các toán tử bậc ba , cho phép các điều kiện trong một chuỗi:

const age = 19 const message = `You can ${age < 21 ? 'not' : ''} view this page` console.log(message) 

Thông báo đã ghi ở đây sẽ thay đổi tùy thuộc vào việc giá trị của age là trên hay dưới 21 . Vì nó là 19 trong ví dụ này, kết quả sau sẽ được ghi lại:

Output
You can not view this page

Đến đây bạn có ý tưởng về cách các ký tự mẫu có thể hữu ích khi được sử dụng để nội suy các biểu thức. Phần tiếp theo sẽ thực hiện điều này một bước xa hơn bằng cách kiểm tra các ký tự mẫu được gắn thẻ để làm việc với các biểu thức được chuyển vào trình giữ chỗ.

Chữ viết mẫu được gắn thẻ

Một tính năng nâng cao của các ký tự mẫu là việc sử dụng các ký tự mẫu được gắn thẻ , đôi khi được gọi là thẻ mẫu . Mẫu được gắn thẻ bắt đầu bằng một hàm thẻ phân tích nghĩa đen của mẫu, cho phép bạn kiểm soát nhiều hơn việc thao tác và trả về một chuỗi động.

Trong ví dụ này, bạn sẽ tạo một hàm tag để sử dụng làm hàm hoạt động trên một mẫu được gắn thẻ. Các chuỗi ký tự là tham số đầu tiên của hàm, các strings được đặt tên ở đây và bất kỳ biểu thức nào được nội suy vào chuỗi được đóng gói thành tham số thứ hai bằng cách sử dụng các tham số còn lại . Bạn có thể điều khiển tham số để xem chúng sẽ chứa những gì:

function tag(strings, ...expressions) {   console.log(strings)   console.log(expressions) } 

Sử dụng hàm tag hàm mẫu được gắn thẻ và phân tích cú pháp chuỗi như sau:

const string = tag`This is a string with ${true} and ${false} and ${100} interpolated inside.` 

Vì bạn đang ghi log console các stringsexpressions , đây sẽ là kết quả :

Output
(4) ["This is a string with ", " and ", " and ", " interpolated inside." (3) [true, false, 100]

Tham số đầu tiên, các strings , là một mảng chứa tất cả các chuỗi ký tự:

  • "This is a string with "
  • " and "
  • " and "
  • " interpolated inside."

Cũng có một thuộc tính raw có sẵn trên đối số này tại strings.raw , chứa các chuỗi mà không có bất kỳ chuỗi thoát nào được xử lý. Ví dụ, /n sẽ chỉ là ký tự /n và không được thoát thành một dòng mới.

Tham số thứ hai, ...expressions , là một mảng tham số còn lại bao gồm tất cả các biểu thức:

  • true
  • false
  • 100

Các ký tự và biểu thức chuỗi được chuyển dưới dạng tham số cho thẻ chức năng mẫu được gắn tag . Lưu ý mẫu được gắn thẻ không cần trả lại một chuỗi; nó có thể hoạt động trên các giá trị đó và trả về bất kỳ loại giá trị nào. Ví dụ, ta có thể có hàm bỏ qua mọi thứ và trả về null , như trong hàm returnsNull này:

function returnsNull(strings, ...expressions) {   return null }  const string = returnsNull`Does this work?` console.log(string) 

Ghi nhật string biến string sẽ trả về:

Output
null

Ví dụ về một hành động có thể được thực hiện trong các mẫu được gắn thẻ là áp dụng một số thay đổi cho cả hai mặt của mỗi biểu thức, chẳng hạn như nếu bạn muốn gói từng biểu thức trong một thẻ HTML. Tạo một hàm bold sẽ thêm <strong></strong> vào mỗi biểu thức:

function bold(strings, ...expressions) {   let finalString = ''    // Loop through all expressions   expressions.forEach((value, i) => {     finalString += `${strings[i]}<strong>${value}</strong>`   })    // Add the last string literal   finalString += strings[strings.length - 1]    return finalString }  const string = bold`This is a string with ${true} and ${false} and ${100} interpolated inside.`  console.log(string) 

Đoạn mã này sử dụng phương thức forEach để lặp qua mảng expressions và thêm phần tử in đậm:

Output
This is a string with <strong>true</strong> and <strong>false</strong> and <strong>100</strong> interpolated inside.

Có một vài ví dụ về các ký tự mẫu được gắn thẻ trong các thư viện JavaScript phổ biến. Thư viện graphql-tag sử dụng mẫu được gắn thẻ gql để phân tích cú pháp các chuỗi truy vấn GraphQL thành cây cú pháp trừu tượng (AST) mà GraphQL hiểu:

import gql from 'graphql-tag'  // A query to retrieve the first and last name from user 5 const query = gql`   {     user(id: 5) {       firstName       lastName     }   } ` 

Một thư viện khác sử dụng các hàm mẫu được gắn thẻ là styled-components được styled-components , cho phép bạn tạo cácthành phần React mới từ các phần tử DOM thông thường và áp dụng các kiểu CSS bổ sung cho chúng:

import styled from 'styled-components'  const Button = styled.button`   color: magenta; `  // <Button> can now be used as a custom component 

Bạn cũng có thể sử dụng phương thức String.raw trên các ký tự mẫu được gắn thẻ để ngăn không cho bất kỳ chuỗi thoát nào được xử lý:

const rawString = String.raw`I want to write /n without it being escaped.` console.log(rawString) 

Điều này sẽ ghi lại những điều sau:

Output
I want to write /n without it being escaped.

Kết luận

Trong bài viết này, bạn đã xem xét các ký tự chuỗi được trích dẫn đơn và kép và bạn đã học về các ký tự mẫu và các ký tự mẫu được gắn thẻ. Các ký tự mẫu làm cho rất nhiều tác vụ chuỗi phổ biến trở nên đơn giản hơn bằng cách nội suy các biểu thức trong chuỗi và tạo chuỗi nhiều dòng mà không có bất kỳ nối hoặc thoát. Thẻ mẫu cũng là một tính năng nâng cao hữu ích của các chữ mẫu mà nhiều thư viện phổ biến đã sử dụng, chẳng hạn như GraphQL và styled-components .

Để tìm hiểu thêm về chuỗi trong JavaScript, hãy đọc Cách làm việc với chuỗi trong JavaScriptCách lập index , tách và thao tác chuỗi trong JavaScript .


Tags:

Các tin liên quan

Cách sử dụng .map () để lặp lại thông qua các mục mảng trong JavaScript
2020-05-19
Hiểu về cấu trúc hủy, tham số khôi phục và cú pháp trải rộng trong JavaScript
2020-05-12
Cách gỡ lỗi JavaScript với Google Chrome DevTools và Visual Studio Code
2020-05-08
Thanh tiến trình trang với các biến JavaScript và CSS
2020-04-16
Xem xét API JavaScript của trình quan sát thay đổi kích thước
2020-04-16
Xem xét API control panel JavaScript
2020-04-16
Xem xét Đề xuất Nhà điều hành Đường ống JavaScript
2020-04-16
Cách triển khai các phương thức mảng JavaScript từ Scratch
2020-04-09
Các đống nhị phân và hàng đợi ưu tiên qua JavaScript
2020-04-05
JavaScript bất biến có thể thay đổi
2020-04-02