diff options
Diffstat (limited to 'files/vi/web/javascript/reference/template_literals/index.html')
-rw-r--r-- | files/vi/web/javascript/reference/template_literals/index.html | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/files/vi/web/javascript/reference/template_literals/index.html b/files/vi/web/javascript/reference/template_literals/index.html new file mode 100644 index 0000000000..3626937740 --- /dev/null +++ b/files/vi/web/javascript/reference/template_literals/index.html @@ -0,0 +1,238 @@ +--- +title: Template literals (Template strings) +slug: Web/JavaScript/Reference/Template_literals +translation_of: Web/JavaScript/Reference/Template_literals +--- +<div>{{JsSidebar("More")}}</div> + +<p>Mẫu nguyên thủy là chuỗi string nguyên thủy cho phép áp dụng vào các biểu thức. Bạn có thể sử dụng các chuỗi nhiều dòng và các chuỗi chức năng nội suy với chúng. Chúng được gọi là "chuỗi mẫu" trong các phiên bản trước của đặc tả ES2015.</p> + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox">`string text` + +`string text line 1 + string text line 2` + +`string text ${expression} string text` + +tag `string text ${expression} string text` +</pre> + +<h2 id="Mô_tả">Mô tả</h2> + +<p>Mẫu nguyên thủy được đóng bởi dấu 'nháy-ngược' (` `) (<a href="https://en.wikipedia.org/wiki/Grave_accent">grave accent</a> - nằm ở góc trái dưới phím Esc) thay vì sử dụng nháy đơn hoặc nháy kép. Mẫunguyên thủy có thể bao gồm placeholders (trong thẻ input có 1 thuộc tính placeholder). Chúng được biểu thị bằng ký hiệu đô la và dấu ngoặc nhọn (<code>${expression}</code>). Các biểu thức trong placeholders và văn bản giữa các dấu 'nháy-ngược' (` `) được đưa vào hàm. Hàm mặc định chỉ ghép các thành phần thành một chuỗi đơn. Nếu có một biểu thức thực hiện trước một mẫu nguyên thủy (<code>tag</code> - ở đây gọi là thẻ), thì được gọi là một "tagged template" (mẫu được gắn thẻ). Trong trường hợp này, biểu thức gắn thẻ (thường là một hàm) được gọi cùng với mẫu nguyên thủy, biểu thức mà sau đó bạn có thể thao tác trước khi trả ra kết quả. Để thoát dấu 'nháy-ngược' trong một mẫu nguyên thủy, hãy đặt dấu gạch chéo ngược \ trước dấu nháyngược (phần này nên note lại và cần tham khảo thêm các ví dụ sau).</p> + +<pre class="brush: js">`\`` === '`' // --> true</pre> + +<h3 id="Các_chuỗi_nhiều_dòng_chuỗi_đa_dòng">Các chuỗi nhiều dòng (chuỗi đa dòng)</h3> + +<p>Bất kỳ các dòng ký tự mới được chèn vào trong nguồn (mã nguồn) đều là một phần của mẫu nguyên thủy. Việc sử dụng các chuỗi mặc định, bạn sẽ phải sử dụng các cú pháp dưới đây để có được các chuỗi đa dòng (sử dụng ký tự \n):</p> + +<pre class="brush: js">console.log('string text line 1\n' + +'string text line 2'); +// "string text line 1 +// string text line 2"</pre> + +<p>Để có được kết quả tượng tự thì sử dụng cú pháp mẫu nguyên thủy, bạn có thể viết như sau:</p> + +<pre class="brush: js">console.log(`string text line 1 +string text line 2`); +// "string text line 1 +// string text line 2"</pre> + +<h3 id="Biểu_thức_nội_suy">Biểu thức nội suy</h3> + +<p>Để nhúng các thiểu thức (hàm, phép tính, ...) vào trong chuỗi mặc định, bạn sẽ sử dụng cú pháp dưới đây:</p> + +<pre class="brush: js">var a = 5; +var b = 10; +console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.'); +// "Fifteen is 15 and +// not 20."</pre> + +<p>Giờ đây, với các mẫu nguyên thủy, bạn có thể sử dụng các thay thế cú pháp như thế này để dễ đọc hơn:</p> + +<pre class="brush: js">var a = 5; +var b = 10; +console.log(`Fifteen is ${a + b} and +not ${2 * a + b}.`); +// "Fifteen is 15 and +// not 20."</pre> + +<h3 id="Các_mẫu_lồng_nhau_mẫu_nằm_trong_mẫu_khác">Các mẫu lồng nhau (mẫu nằm trong mẫu khác)</h3> + +<p>Trong một số trường hợp nhất định, lồng một mẫu là cách dễ nhất và có thể dễ đọc hơn để có các chuỗi có khả năng cấu hình. Bên trong một mẫu được tạo, nó đơn giản để cho phép các dấu nháy ngược bên trong chỉ đơn giản bằng cách sử dụng chúng trong một placeholder <code>${ }</code> bên trong mẫu. Ví dụ, nếu điều kiện đúng: thì trả về mẫu nguyên thủy.</p> + +<p>Trong ES5:</p> + +<pre class="brush: js">var classes = 'header' +classes += (isLargeScreen() ? + '' : item.isCollapsed ? + ' icon-expander' : ' icon-collapser'); +</pre> + +<p>Trong ES2015 với mẫu nguyên thủy và không đặt lồng nhau:</p> + +<pre class="brush: js">const classes = `header ${ isLargeScreen() ? '' : + (item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`;</pre> + +<p>Trong ES2015 với 2 mẫu nguyên thủy đặt lồng nhau:</p> + +<pre class="brush: js">const classes = `header $<strong>{</strong> isLargeScreen() ? '' : + `icon-${item.isCollapsed ? 'expander' : 'collapser'}`<strong> </strong><strong>}`</strong>;</pre> + +<h3 id="Các_mẫu_được_gắn_thẻ">Các mẫu được gắn thẻ</h3> + +<p>Một hình thức nâng cao hơn của mẫu nguyên thủy là các mẫu được gắn thẻ. Các thẻ cho phép bạn chuyển đổi các mẫu nguyên thủy sử dụng hàm. Tham số đầu tiên của hàm gắn thẻ bao gồm một mảng các chuỗi. Các tham số còn lại được gắn với các biểu thức. Cuối cùng, hàm của bạn có thể trả về chuỗi được thao tác (hoặc nó có thể trả về bất kỳ kết quả gì theo mục đích lập trình trong ví dụ tiếp theo). Tê của hàm được sử dụng cho thẻ bạn có thể đặt tên theo cách bạn muốn.</p> + +<pre class="brush: js">var person = 'Mike'; +var age = 28; + +function myTag(strings, personExp, ageExp) { + var str0 = strings[0]; // "That " + var str1 = strings[1]; // " is a " + + // There is technically a string after + // the final expression (in our example), + // but it is empty (""), so disregard. + // var str2 = strings[2]; + + var ageStr; + if (ageExp > 99){ + ageStr = 'centenarian'; + } else { + ageStr = 'youngster'; + } + + // We can even return a string built using a template literal + return `${str0}${personExp}${str1}${ageStr}`; +} + +var output = myTag`That ${ person } is a ${ age }`; + +console.log(output); +// That Mike is a youngster</pre> + +<p>Các hàm gắn thẻ không cần trả về một chuỗi, như được hiển thị ở ví dụ dưới đây.</p> + +<pre class="brush: js">function template(strings, ...keys) { + return (function(...values) { + var dict = values[values.length - 1] || {}; + var result = [strings[0]]; + keys.forEach(function(key, i) { + var value = Number.isInteger(key) ? values[key] : dict[key]; + result.push(value, strings[i + 1]); + }); + return result.join(''); + }); +} + +var t1Closure = template`${0}${1}${0}!`; +t1Closure('Y', 'A'); // "YAY!" +var t2Closure = template`${0} ${'foo'}!`; +t2Closure('Hello', {foo: 'World'}); // "Hello World!" +</pre> + +<h3 id="Các_chuỗi_chưa_xử_lý_chuỗi_thô">Các chuỗi chưa xử lý (chuỗi thô)</h3> + +<p>thuộc tính <code>raw</code> khá đặc biệt, có thể trong tham số đầu tiên để gán thẻ hàm, nó cho phép bạn truy cập các chuỗi thô như khi chúng được đưa vào, không cần sử lý <a href="/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Using_special_characters_in_strings">escape sequences</a>.</p> + +<pre class="brush: js">function tag(strings) { + console.log(strings.raw[0]); +} + +tag`string text line 1 \n string text line 2`; +// logs "string text line 1 \n string text line 2" , +// including the two characters '\' and 'n' +</pre> + +<p>Ngoài ra, phương thức {{jsxref("String.raw()")}} tồn tại để tạo các chuỗi thô giống như hàm mẫu mặc định và chuỗi nối.</p> + +<pre class="brush: js">var str = String.raw`Hi\n${2+3}!`; +// "Hi\n5!" + +str.length; +// 6 + +str.split('').join(','); +// "H,i,\,n,5,!" +</pre> + +<h3 id="Mẫu_được_gắn_thẻ_và_trình_tự_thoát">Mẫu được gắn thẻ và trình tự thoát</h3> + +<h4 id="ES2016_behavior">ES2016 behavior</h4> + +<p>Trong ECMAScript 2016, các mẫu được gắn thẻ tuân theo quy tắc của các trình tự thoát sau đây:</p> + +<ul> + <li>Unicode escapes bắt đầu bởi "\u", ví dụ <code>\u00A9</code></li> + <li>Unicode code point escapes chỉ định bởi "\u{}", ví dụ <code>\u{2F804}</code></li> + <li>Hexadecimal escapes bắt đầu bởi "\x", ví dụ <code>\xA9</code></li> + <li>Octal nguyên thủy escapes bắt đầu bởi "\0o" và được gán thêm bằng một hay nhiều chữ số, ví dụ <code>\0o251</code></li> +</ul> + +<p>Điều này có nghĩa là một mẫu được gắn thẻ như sau là có vấn đề, bởi vì mỗi ngữ pháp ECMAScript, một phân tích trông như đúng trình tự Unicode escape:</p> + +<pre class="brush: js">latex`\unicode` +// Throws in older ECMAScript versions (ES2016 and earlier) +// SyntaxError: malformed Unicode character escape sequence</pre> + +<h4 id="ES2018_sửa_đổi_các_chuỗi_thoát_bất_hợp_pháp">ES2018 sửa đổi các chuỗi thoát bất hợp pháp</h4> + +<p>Các mẫu được gắn thẻ sẽ cho phép nhúng các ngôn ngữ (ví dụ <a href="https://en.wikipedia.org/wiki/Domain-specific_language">DSLs</a>, or <a href="https://en.wikipedia.org/wiki/LaTeX">LaTeX</a>), trong đó các chuỗi thoát khác là phổ biến. ECMAScript đề xuất <a href="https://tc39.github.io/proposal-template-literal-revision/">Template Literal Revision</a> (giai đoạn 4, được tích hợp trong tiêu chuẩn ECMAScript 2018) xóa giới hạn cú pháp của chuỗi thoát ECMAScript khỏi các mẫu được gắn thẻ.</p> + +<p>Tuy nhiên, các chuỗi thoát bất hợp pháp vẫn phải được giữ lại. Chúng sẽ hiển thị như thành phần {{jsxref("undefined")}} trong mảng “cooked”:</p> + +<pre class="brush: js">function latex(str) { + return { "cooked": str[0], "raw": str.raw[0] } +} + +latex`\unicode` + +// { cooked: undefined, raw: "\\unicode" }</pre> + +<p>Chú ý rằng hạn chế trình tự thoát chỉ được loại bỏ khỏi các mẫu được gắn thẻ chứ không phải từ các mẫu chữ không được đánh dấu:</p> + +<pre class="brush: js example-bad">let bad = `bad escape sequence: \unicode`;</pre> + +<h2 id="Thông_số_kỹ_thuật">Thông số kỹ thuật</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-template-literals', 'Template Literals')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition. Defined in several section of the specification: <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-template-literals">Template Literals</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-tagged-templates">Tagged Templates</a></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-template-literals', 'Template Literals')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td>Defined in several section of the specification: <a href="https://tc39.github.io/ecma262/#sec-template-literals">Template Literals</a>, <a href="https://tc39.github.io/ecma262/#sec-tagged-templates">Tagged Templates</a></td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<div> + + +<p>{{Compat("javascript.grammar.template_literals")}}</p> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{jsxref("String")}}</li> + <li>{{jsxref("String.raw()")}}</li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar">Lexical grammar</a></li> + <li><a href="https://gist.github.com/WebReflection/8f227532143e63649804">Template-like strings in ES3 compatible syntax</a></li> + <li><a href="https://hacks.mozilla.org/2015/05/es6-in-depth-template-strings-2/">"ES6 in Depth: Template strings" on hacks.mozilla.org</a></li> + <li><a href="https://styled-components.com/">https://styled-components.com/</a></li> +</ul> |