diff options
Diffstat (limited to 'files/vi/web/javascript/reference/statements')
9 files changed, 1673 insertions, 0 deletions
diff --git a/files/vi/web/javascript/reference/statements/async_function/index.html b/files/vi/web/javascript/reference/statements/async_function/index.html new file mode 100644 index 0000000000..3009b78083 --- /dev/null +++ b/files/vi/web/javascript/reference/statements/async_function/index.html @@ -0,0 +1,255 @@ +--- +title: async function +slug: Web/JavaScript/Reference/Statements/async_function +translation_of: Web/JavaScript/Reference/Statements/async_function +--- +<div> +<div>{{jsSidebar("Statements")}}<br> +<span class="seoSummary">Việc tạo hàm với câu lệnh <code><strong>async function</strong></code> sẽ định nghĩa ra một <strong>hàm không đồng bộ (asynchronous function)</strong> - hàm này sẽ trả về một object {{jsxref("Global_Objects/AsyncFunction","AsyncFunction")}}</span></div> + +<p>Các hàm không đồng bộ sẽ hoạt động trong một thứ tự tách biệt so với phần còn lại của đoạn code thông qua một <a href="/en-US/docs/Web/JavaScript/EventLoop">event loop</a>, trả về kết quả là một {{jsxref("Promise")}} tiềm ẩn. Nhưng cú pháp và cấu trúc của đoạn code mà sử dụng các hàm async function trông cứ như những hàm đồng bộ tiêu chuẩn.</p> + +<div class="noinclude"> +<p>Bạn cũng có thể định nghĩa các async function với một {{jsxref("Operators/async_function", "async function expression", "", 1)}}.</p> +</div> +</div> + +<div>{{EmbedInteractiveExample("pages/js/statement-async.html", "taller")}}</div> + +<p class="hidden">The source for this interactive demo is stored in a GitHub repository. If you'd like to contribute to the interactive demo project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</p> + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox">async function <var>name</var>([<var>param</var>[, <var>param</var>[, ...<var>param</var>]]]) { + <var>statements</var> +} +</pre> + +<h3 id="Các_thông_số">Các thông số</h3> + +<dl> + <dt><code><var>name</var></code></dt> + <dd>Tên của function.</dd> + <dt><code><var>param</var></code></dt> + <dd>Tên của một đối số được truyền vào function.</dd> + <dt><code><var>statements</var></code></dt> + <dd>Các câu lệnh bao hàm phần thân của function.</dd> +</dl> + +<h3 id="Giá_trị_trả_về">Giá trị trả về</h3> + +<p>Một <code><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a></code>, cái mà sẽ được giải quyết với giá trị được trả về bởi async function, hoặc được đẩy ra ngoài với một exception không được bắt lại bên trong hàm async function.</p> + +<h2 id="Mô_tả">Mô tả</h2> + +<p>Một hàm async có thể bao gồm một biểu thức {{jsxref("Operators/await", "await")}}, biểu thức này sẽ tạm dừng việc thực thi của hàm async để chờ cho <code>Promise's resolution</code> được truyền vào, sau đó tiếp tục việc thực thi của hàm <code>async</code> and evaluates as the resolved value.</p> + +<p><strong>Từ khóa await chỉ có hiệu lực bên trong hàm <code>async</code>.</strong> Nếu bạn sử dụng nó bên ngoài phần thân của hàm <code>async</code>, bạn sẽ nhận một <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError">SyntaxError</a></code>.</p> + +<p>Trong lúc hàm async tạm dừng, hàm được gọi sẽ tiếp tục chạy. (hàm mà nhận được Promise tiềm ẩn được trả về bởi hàm <code>async</code>).</p> + +<div class="note"> +<p>Mục đích của <code>async</code>/<code>await</code> là để đơn giả hóa việc sử dụng các promises một cách đồng bộ, và để triển khai một số hoạt động trên một nhóm của các <code>Promises</code>. Nếu <code>Promises </code>là tương tự như các callback có cấu trúc, <code>async</code>/<code>await </code>là tương tự với kết hợp các <a href="/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators">generators</a> và promises.</p> +</div> + +<h2 id="Ví_dụ">Ví dụ</h2> + +<h3 id="Async_functions_và_thứ_tự_của_việc_thực_thi">Async functions và thứ tự của việc thực thi</h3> + +<pre class="brush: js">function resolveAfter2Seconds() { + console.log("starting slow promise") + return new Promise(resolve => { + setTimeout(function() { + resolve("slow") + console.log("slow promise is done") + }, 2000) + }) +} + +function resolveAfter1Second() { + console.log("starting fast promise") + return new Promise(resolve => { + setTimeout(function() { + resolve("fast") + console.log("fast promise is done") + }, 1000) + }) +} + +async function sequentialStart() { + console.log('==SEQUENTIAL START==') + + // 1. Execution gets here almost instantly + const slow = await resolveAfter2Seconds() + console.log(slow) // 2. this runs 2 seconds after 1. + + const fast = await resolveAfter1Second() + console.log(fast) // 3. this runs 3 seconds after 1. +} + +async function concurrentStart() { + console.log('==CONCURRENT START with await=='); + const slow = resolveAfter2Seconds() // starts timer immediately + const fast = resolveAfter1Second() // starts timer immediately + + // 1. Execution gets here almost instantly + console.log(await slow) // 2. this runs 2 seconds after 1. + console.log(await fast) // 3. this runs 2 seconds after 1., immediately after 2., since fast is already resolved +} + +function concurrentPromise() { + console.log('==CONCURRENT START with Promise.all==') + return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => { + console.log(messages[0]) // slow + console.log(messages[1]) // fast + }) +} + +async function parallel() { + console.log('==PARALLEL with await Promise.all==') + + // Start 2 "jobs" in parallel and wait for both of them to complete + await Promise.all([ + (async()=>console.log(await resolveAfter2Seconds()))(), + (async()=>console.log(await resolveAfter1Second()))() + ]) +} + +// This function does not handle errors. See warning below! +function parallelPromise() { + console.log('==PARALLEL with Promise.then==') + resolveAfter2Seconds().then((message)=>console.log(message)) + resolveAfter1Second().then((message)=>console.log(message)) +} + +sequentialStart() // after 2 seconds, logs "slow", then after 1 more second, "fast" + +// wait above to finish +setTimeout(concurrentStart, 4000) // after 2 seconds, logs "slow" and then "fast" + +// wait again +setTimeout(concurrentPromise, 7000) // same as concurrentStart + +// wait again +setTimeout(parallel, 10000) // truly parallel: after 1 second, logs "fast", then after 1 more second, "slow" + +// wait again +setTimeout(parallelPromise, 13000) // same as parallel +</pre> + +<h4 id="await_và_xử_lý_song_song"><code>await</code> và xử lý song song</h4> + +<p>In <code>sequentialStart</code>, execution suspends 2 seconds for the first <code>await</code>, and then another second for the second <code>await</code>. The second timer is not created until the first has already fired, so the code finishes after 3 seconds.</p> + +<p>In <code>concurrentStart</code>, both timers are created and then <code>await</code>ed. The timers run concurrently, which means the code finishes in 2 rather than 3 seconds, i.e. the slowest timer.<br> + However, the <code>await</code> calls still run in series, which means the second <code>await</code> will wait for the first one to finish. In this case, the result of the fastest timer is processed after the slowest.</p> + +<p>If you wish to fully perform two or more jobs in parallel, you must use <code>await Promise.all([job1(), job2()])</code>, as shown in the <code>parallel</code> example.</p> + +<div class="warning"> +<h4 id="asyncawait_vs_Promise.then_and_error_handling"><code>async</code>/<code>await</code> vs <code>Promise.then</code> and error handling</h4> + +<p>Most async functions can also be written as regular functions using Promises. However, <code>async</code> functions are less tricky when it comes to error handling.</p> + +<p>Both <code>concurrentStart</code> and <code>concurrentPromise</code> are functionally equivalent:</p> + +<ul> + <li>In <code>concurrentStart</code>, if either of the <code>await</code>ed calls fail, the exception will be automatically caught, the async function execution interrupted, and the Error propagated to the caller through the implicit return Promise.</li> + <li>For the same to happen in the Promise case, the function must take care of returning a <code>Promise</code> which captures the completion of the function. In <code>concurrentPromise</code> that means <code>return</code>ing the promise from <code>Promise.all([]).then()</code>. As a matter of fact, a previous version of this example forgot to do this!</li> +</ul> + +<p>It is, however, still possible for <code>async</code> functions to mistakenly swallow errors.</p> + +<p>Take, for example the <code>parallel</code> async function. If it didn't <code>await</code> (or <code>return</code>) the result of the <code>Promise.all([])</code> call, any Error would not propagate.</p> + +<p>While the <code>parallelPromise</code> example seems simpler, it does not handle errors at all! Doing so would require a similar <code>return </code><code>Promise.all([])</code>.</p> +</div> + +<h3 id="Rewriting_a_Promise_chain_with_an_async_function">Rewriting a Promise chain with an <code>async</code> function</h3> + +<p>An API that returns a {{jsxref("Promise")}} will result in a promise chain, and it splits the function into many parts. Consider the following code:</p> + +<pre class="brush: js">function getProcessedData(url) { + return downloadData(url) // returns a promise + .catch(e => { + return downloadFallbackData(url) // returns a promise + }) + .then(v => { + return processDataInWorker(v) // returns a promise + }) +} +</pre> + +<p>it can be rewritten with a single <code>async</code> function as follows:</p> + +<pre class="brush: js">async function getProcessedData(url) { + let v + try { + v = await downloadData(url) + } catch(e) { + v = await downloadFallbackData(url) + } + return processDataInWorker(v) +} +</pre> + +<p>In the above example, there is no <code>await</code> statement after the <code>return</code> keyword, because the return value of an <code>async function</code> is implicitly wrapped in {{jsxref("Promise.resolve")}}.</p> + +<div class="blockIndicator note"> +<h4 id="return_await_promiseValue_vs._return_promiseValue"><code>return await promiseValue</code> vs. <code>return promiseValue</code></h4> + +<p>The implicit wrapping of return values in {{jsxref("Promise.resolve")}} does not imply that <code>return await promiseValue</code> is functionally equivalent to <code>return promiseValue</code>.</p> + +<p>Consider the following rewrite of the above code. It returns <code>null</code> if <code>processDataInWorker</code> rejects with an error:</p> + +<pre class="brush: js">async function getProcessedData(url) { + let v + try { + v = await downloadData(url) + } catch(e) { + v = await downloadFallbackData(url) + } + try { + return await processDataInWorker(v) // Note the `return await` vs. just `return` + } catch (e) { + return null + } +} +</pre> + +<p>Writing <code>return processDataInWorker(v)</code> would have caused the {{jsxref("Promise")}} returned by the function to reject, instead of resolving to <code>null</code> if <code>processDataInWorker(v)</code> rejects.</p> + +<p>This highlights the subtle difference between <code>return foo;</code> and <code>return await foo;</code> — <code>return foo</code> immediately returns <code>foo</code> and never throws, even if <code>foo</code> is a Promise that rejects. <code>return await foo</code> will <em>wait </em>for <code>foo</code> to resolve or reject if it's a Promise, and throws <strong>before returning</strong> if it rejects.</p> +</div> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<div> + + +<p>{{Compat("javascript.statements.async_function")}}</p> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{jsxref("Operators/async_function", "async function expression")}}</li> + <li>{{jsxref("AsyncFunction")}} object</li> + <li>{{jsxref("Operators/await", "await")}}</li> + <li><a href="http://innolitics.com/10x/javascript-decorators-for-promise-returning-functions/">"Decorating Async Javascript Functions" on "innolitics.com"</a></li> +</ul> diff --git a/files/vi/web/javascript/reference/statements/continue/index.html b/files/vi/web/javascript/reference/statements/continue/index.html new file mode 100644 index 0000000000..d6afd506d7 --- /dev/null +++ b/files/vi/web/javascript/reference/statements/continue/index.html @@ -0,0 +1,135 @@ +--- +title: continue +slug: Web/JavaScript/Reference/Statements/continue +translation_of: Web/JavaScript/Reference/Statements/continue +--- +<div>{{jsSidebar("Statements")}}</div> + +<p>Câu lệnh <strong>continue </strong>chấm dứt việc thực thi của các câu lệnh trong lượt lặp hiện tại của vòng lặp hiện tại, hoặc của vòng lặp được gắn nhãn, và tiếp tục việc thực thi lượt lặp kế tiếp.</p> + +<div>{{EmbedInteractiveExample("pages/js/statement-continue.html")}}</div> + +<p class="hidden">Nguồn cho ví dụ tương tác này được lưu trữ trên GitHub repository. Nếu bạn muốn đóng góp vào các dự án ví dụ tương tác, hãy clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> và send a pull request.</p> + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox">continue [<em>label</em>];</pre> + +<dl> + <dt><code>label</code></dt> + <dd>Identifier gắn liền với nhãn của câu lệnh.</dd> +</dl> + +<h2 id="Mô_tả">Mô tả</h2> + +<p>Trái ngược với câu lệnh {{jsxref("Statements/break", "break")}}, <code>continue</code> không chấm dứt việc thực thi của cả vòng lặp: thay vào đó,</p> + +<ul> + <li>Trong một vòng lặp {{jsxref("Statements/while", "while")}}, nó nhảy trở về biểu thức điều kiện.</li> + <li>Trong một vòng lặp {{jsxref("Statements/for", "for")}}, nó nhảy đến biểu thức tăng tiến (update expression).</li> +</ul> + +<p>Câu lệnh <code>continue</code> có thể bao gồm một nhãn tùy chọn cho phép chương trình nhảy đến lượt lặp tiếp theo của một câu lệnh vòng lặp được gắn nhãn, thay vì nhảy đến lượt lặp tiếp theo của vòng lặp hiện tại. Trong trường hợp này, câu lệnh <code>continue</code> cần được lồng bên trong câu lệnh được gắn nhãn đó.</p> + +<h2 id="Ví_dụ">Ví dụ</h2> + +<h3 id="Sử_dụng_continue_với_while">Sử dụng continue với while</h3> + +<p>Ví dụ sau thể hiện một vòng lặp {{jsxref("Statements/while", "while")}} có một câu lệnh <code>continue</code> mà sẽ được thực thi khi giá trị của <code>i</code> là 3. Vì vậy, <code>n</code> nhận các giá trị 1, 3, 7 và 12.</p> + +<pre class="brush: js">var i = 0; +var n = 0; + +while (i < 5) { + i++; + + if (i === 3) { + continue; + } + + n += i; +} +</pre> + +<h3 id="Sử_dụng_continue_với_một_nhãn_label">Sử dụng continue với một nhãn (label)</h3> + +<p>Trong ví dụ sau đây, một câu lệnh được gắn nhãn <code>checkiandj</code> có chứa một câu lệnh được gắn nhãn <code>checkj</code>. Nếu gặp phải <code>continue</code>, chương trình sẽ tiếp tục tại phần đầu của câu lệnh <code>checkj</code>. Mỗi lần gặp phải <code>continue</code>, <code>checkj</code> sẽ chạy lại cho đến khi điều kiện của nó trả về false. Khi false được trả về, phần còn lại của câu lệnh <code>checkiandj</code> sẽ được hoàn thành.</p> + +<p>Nếu sau <code>continue</code> có một nhãn <code>checkiandj</code>, chương trình sẽ tiếp túc tại phần đầu của câu lệnh <code>checkiandj</code>.</p> + +<p>Xem thêm {{jsxref("Statements/label", "label")}}.</p> + +<pre class="brush: js">var i = 0; +var j = 8; + +checkiandj: while (i < 4) { + console.log('i: ' + i); + i += 1; + + checkj: while (j > 4) { + console.log('j: ' + j); + j -= 1; + + if ((j % 2) == 0) + continue checkj; + console.log(j + ' is odd.'); + } + console.log('i = ' + i); + console.log('j = ' + j); +} +</pre> + +<p>Kết quả:</p> + +<pre class="brush: js">i: 0 + +// start checkj +j: 8 +7 is odd. +j: 7 +j: 6 +5 is odd. +j: 5 +// end checkj + +i = 1 +j = 4 + +i: 1 +i = 2 +j = 4 + +i: 2 +i = 3 +j = 4 + +i: 3 +i = 4 +j = 4 +</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-continue-statement', 'Continue statement')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.statements.continue")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{jsxref("Statements/break", "break")}}</li> + <li>{{jsxref("Statements/label", "label")}}</li> +</ul> diff --git a/files/vi/web/javascript/reference/statements/do...while/index.html b/files/vi/web/javascript/reference/statements/do...while/index.html new file mode 100644 index 0000000000..eef8cf1f08 --- /dev/null +++ b/files/vi/web/javascript/reference/statements/do...while/index.html @@ -0,0 +1,98 @@ +--- +title: do...while +slug: Web/JavaScript/Reference/Statements/do...while +translation_of: Web/JavaScript/Reference/Statements/do...while +--- +<div>{{jsSidebar("Statements")}}</div> + +<p><strong>Vòng lặp</strong> <strong><code>do...while</code></strong> tạo ra vòng lặp thực thi các câu lệnh bên trong nó đến khi điều kiện không còn thoả mãn nữa. Điều kiện của vòng lặp sẽ được kiểm tra sau thực thi các câu lệnh, các câu lệnh của vòng lặp sẽ được thực thi ít nhất một lần.</p> + +<div>{{EmbedInteractiveExample("pages/js/statement-dowhile.html")}}</div> + + + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox">do + <em>// các câu lệnh</em> +while (<em>// điều kiện</em>); +</pre> + +<dl> + <dt><code>statement</code></dt> + <dd>A statement that is executed at least once and is re-executed each time the condition evaluates to true. To execute multiple statements within the loop, use a {{jsxref("Statements/block", "block")}} statement (<code>{ ... }</code>) to group those statements.</dd> +</dl> + +<dl> + <dt><code>condition</code></dt> + <dd>An expression evaluated after each pass through the loop. If <code>condition</code> evaluates to true, the <code>statement</code> is re-executed. When <code>condition</code> evaluates to false, control passes to the statement following the <code>do...while</code>.</dd> +</dl> + +<h2 id="Examples" name="Examples">Examples</h2> + +<h3 id="Using_do...while">Using <code>do...while</code></h3> + +<p>In the following example, the <code>do...while</code> loop iterates at least once and reiterates until <code>i</code> is no longer less than 5.</p> + +<h3 id="HTML_content">HTML content</h3> + +<pre class="brush: html"><div id="example"></div></pre> + +<h3 id="JavaScript_content">JavaScript content</h3> + +<pre class="brush: js">var result = ''; +var i = 0; +do { + i += 1; + result += i + ' '; +} while (i < 5); +document.getElementById('example').innerHTML = result;</pre> + +<h3 id="Result">Result</h3> + +<p>{{ EmbedLiveSample('Examples') }}</p> + +<h2 id="Specifications">Specifications</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('ES3')}}</td> + <td>{{Spec2('ES3')}}</td> + <td>Initial definition. Implemented in JavaScript 1.2</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-12.6.1', 'do-while statement')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-do-while-statement', 'do-while statement')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Trailing ; is now optional.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-do-while-statement', 'do-while statement')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.statements.do_while")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{jsxref("Statements/while", "while")}}</li> + <li>{{jsxref("Statements/for", "for")}}</li> +</ul> diff --git a/files/vi/web/javascript/reference/statements/export/index.html b/files/vi/web/javascript/reference/statements/export/index.html new file mode 100644 index 0000000000..0187b3dbfa --- /dev/null +++ b/files/vi/web/javascript/reference/statements/export/index.html @@ -0,0 +1,186 @@ +--- +title: export +slug: Web/JavaScript/Reference/Statements/export +translation_of: Web/JavaScript/Reference/Statements/export +--- +<div>{{jsSidebar("Statements")}}</div> + +<p>Lệnh <strong><code>export</code></strong> được sử dụng khi tạo các module JavaScript để export các hàm, đối tượng hoặc giá trị nguyên thủy trong module để chúng có thể được sử dụng bởi các chương trình khác bằng lệnh {{jsxref("Statements/import", "import")}}.</p> + +<div class="note"> +<p>Tính năng này mới chỉ được triển khai trên Safari vào thời điểm hiện tại. Nó cũng được triển khai ở nhiều trình dịch (transpilers), ví dụ như <a href="https://github.com/google/traceur-compiler">Traceur Compiler</a>, <a href="http://babeljs.io/">Babel</a> hay <a href="https://github.com/rollup/rollup">Rollup</a>.</p> +</div> + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox">export { <var>name1</var>, <var>name2</var>, …, <var>nameN</var> }; +export { <var>variable1</var> as <var>name1</var>, <var>variable2</var> as <var>name2</var>, …, <var>nameN</var> }; +export let <var>name1</var>, <var>name2</var>, …, <var>nameN</var>; // còn có thể là var, function +export let <var>name1</var> = …, <var>name2</var> = …, …, <var>nameN</var>; // còn có thể là var, const + +export default <em>expression</em>; +export default function (…) { … } // còn có thể là class, function* +export default function name1(…) { … } // còn có thể là class, function* +export { <var>name1</var> as default, … }; + +export * from …; +export { <var>name1</var>, <var>name2</var>, …, <var>nameN</var> } from …; +export { <var>import1</var> as <var>name1</var>, <var>import2</var> as <var>name2</var>, …, <var>nameN</var> } from …;</pre> + +<dl> + <dt><code>nameN</code></dt> + <dd>Định danh được export (để có thể được import thông qua lệnh {{jsxref("Statements/import", "import")}} ở trong script khác).</dd> +</dl> + +<h2 id="Mô_tả">Mô tả</h2> + +<p>Có nhiều kiểu export khác nhau. Mỗi kiểu tương ứng với một trong các cú pháp ở phía trên:</p> + +<ul> + <li>Export tên: + <pre class="brush: js">// exports một hàm được định nghĩa phía trước +export { myFunction }; + +// exports một hằng số +export const foo = Math.sqrt(2);</pre> + </li> + <li>Export giá trị mặc định (hàm): + <pre class="brush: js">export default function() {} </pre> + </li> + <li>Export giá trị mặc định (lớp): + <pre class="brush: js">export default class {} </pre> + </li> +</ul> + +<p>Export tên hữu ích khi dùng để export một vài giá trị. Khi import, có thể dùng cùng tên đó để truy xuất đến giá trị tương ứng.</p> + +<p>Về export giá trị mặc định, chỉ có duy nhất một giá trị mặc định được export trên một module. Một giá trị được export mặc định có thể là một hàm, một lớp, một đối tượng hay bất cứ thứ gì khác. Giá trị này được coi là giá trị được export "chính" do nó sẽ là giá trị đơn giản nhất được import.</p> + +<p>Export các giá trị mặc định: Cú pháp sau đây không export một giá trị được export mặc định từ module được import:</p> + +<pre>export * from …;</pre> + +<p>Nếu bạn muốn export giá trị mặc định, hãy dùng cú pháp sau:</p> + +<pre>import mod from "mod"; +export default mod;</pre> + +<h2 id="Ví_dụ">Ví dụ</h2> + +<h3 id="Sử_dụng_export_tên">Sử dụng export tên</h3> + +<p>Trong module, chúng ta có thể dùng code sau:</p> + +<pre class="brush: js">// module "my-module.js" +function cube(x) { + return x * x * x; +} +const foo = Math.PI + Math.SQRT2; +export { cube, foo }; +</pre> + +<p>Với cách này, trong script khác (cf. <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/import">import</a></code>), chúng ta có:</p> + +<pre class="brush: js">import { cube, foo } from 'my-module'; +console.log(cube(3)); // 27 +console.log(foo); // 4.555806215962888</pre> + +<h3 id="Sử_dụng_export_giá_trị_mặc_định">Sử dụng export giá trị mặc định</h3> + +<p>Nếu chúng ta muốn export một giá trị duy nhất hay có một giá trị trả về mặc định từ module của mình, chúng ta có thể sử dụng export giá trị mặc định:</p> + +<pre class="brush: js">// module "my-module.js" +export default function cube(x) { + return x * x * x; +} +</pre> + +<p>Sau đó, trong script khác, có thể import thẳng giá trị được export mặc định:</p> + +<pre class="brush: js">import cube from 'my-module'; +console.log(cube(3)); // 27 +</pre> + +<p>Chú ý là không thể dùng <code>var</code>, <code>let</code> hay <code>const</code> với <code>export default</code>.</p> + +<h2 id="Đặc_tả">Đặc tả</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Đặc tả</th> + <th scope="col">Trạng thái</th> + <th scope="col">Chú thích</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-exports', 'Exports')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Định nghĩa ban đầu.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-exports', 'Exports')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Tương_thích_với_trình_duyệt">Tương thích với trình duyệt</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Tính năng</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Hỗ trợ cơ bản</td> + <td>61 (60 w/ flag)</td> + <td>{{CompatNo}} (54 w/ flag)</td> + <td>{{CompatNo}} (15 w/flag)</td> + <td>{{CompatNo}}</td> + <td>10.1</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Tính năng</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Hỗ trợ cơ bản</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>10.3</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="Xem_thêm">Xem thêm</h2> + +<ul> + <li>{{jsxref("Statements/import", "import")}}</li> + <li><a href="https://hacks.mozilla.org/2015/08/es6-in-depth-modules/">ES6 in Depth: Modules</a>, Hacks blog đăng bởi Jason Orendorff</li> + <li><a href="http://exploringjs.com/es6/ch_modules.html">Axel Rauschmayer's book: "Exploring JS: Modules"</a></li> +</ul> diff --git a/files/vi/web/javascript/reference/statements/for...of/index.html b/files/vi/web/javascript/reference/statements/for...of/index.html new file mode 100644 index 0000000000..5bd72040eb --- /dev/null +++ b/files/vi/web/javascript/reference/statements/for...of/index.html @@ -0,0 +1,318 @@ +--- +title: for...of +slug: Web/JavaScript/Reference/Statements/for...of +tags: + - ECMAScript 2015 + - JavaScript + - Reference + - Statement +translation_of: Web/JavaScript/Reference/Statements/for...of +--- +<div>{{jsSidebar("Statements")}}</div> + +<p>Cú pháp <strong><code>for...of</code></strong> để chạy <a href="/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol">vòng lặp </a> trên {{jsxref("String")}}, {{jsxref("Array")}}, đối tượng tương tự <code>Array</code> (như {{jsxref("Functions/arguments", "arguments")}} hoặc {{domxref("NodeList")}}), {{jsxref("TypedArray")}}, {{jsxref("Map")}}, {{jsxref("Set")}}.</p> + +<div>{{EmbedInteractiveExample("pages/js/statement-forof.html")}}</div> + +<p class="hidden">Ví dụ được lưu trên GitHub repository. Nếu muốn đóng góp, bạn có thể clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> và gởi lên pull request.</p> + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox notranslate">for (<em>tên-biến</em> of <em>đối-tượng-chạy-vòng-lặp</em>) { + <em>...câu lệnh...</em> +} +</pre> + +<dl> + <dt><code>tên biến</code></dt> + <dd><br> + Trên mỗi lần lặp, một giá trị của một thuộc tính khác nhau được gán cho biến. biến có thể được khai báo với const, let hoặc var.</dd> + <dt><code>đối tượng để chạy vòng lặp</code></dt> + <dd>Đối tượng có các thuộc tính có thể được lặp lại (<em>iterable</em>).</dd> +</dl> + +<h2 id="Ví_dụ">Ví dụ</h2> + +<h3 id="Lặp_qua_một_jsxrefArray">Lặp qua một {{jsxref("Array")}}</h3> + +<pre class="brush:js notranslate">let iterable = [10, 20, 30]; + +for (let value of iterable ) { + value += 1; + console.log(value); +} +// 11 +// 21 +// 31 +</pre> + +<p>Có thể khai báo bằng <a href="/en-US/docs/Web/JavaScript/Reference/Statements/const"><code>const</code></a> thay cho <a href="/en-US/docs/Web/JavaScript/Reference/Statements/let"><code>let</code></a>, nếu không có thay đổi biến bên trong vòng lặp.</p> + +<pre class="brush:js notranslate">let iterable= [10, 20, 30]; + +for (const value of iterable) { + console.log(value); +} +// 10 +// 20 +// 30 +</pre> + +<h3 id="Lặp_qua_một_jsxrefString">Lặp qua một {{jsxref("String")}}</h3> + +<pre class="brush:js notranslate">const iterable = 'boo'; + +for (const value of iterable) { + console.log(value); +} +// "b" +// "o" +// "o" +</pre> + +<h3 id="Lặp_qua_jsxrefTypedArray">Lặp qua {{jsxref("TypedArray")}}</h3> + +<pre class="brush:js notranslate">const iterable = new Uint8Array([0x00, 0xff]); + +for (const value of iterable) { + console.log(value); +} +// 0 +// 255 +</pre> + +<h3 id="Lặp_qua_một_jsxrefMap">Lặp qua một {{jsxref("Map")}}</h3> + +<pre class="brush:js notranslate">const iterable = new Map([['a', 1], ['b', 2], ['c', 3]]); + +for (const entry of iterable) { + console.log(entry); +} +// ['a', 1] +// ['b', 2] +// ['c', 3] + +for (const [key, value] of iterable) { + console.log(value); +} +// 1 +// 2 +// 3 +</pre> + +<h3 id="Loop_qua_một_jsxrefSet">Loop qua một {{jsxref("Set")}}</h3> + +<pre class="brush:js notranslate">const iterable = new Set([1, 1, 2, 2, 3, 3]); + +for (const value of iterable) { + console.log(value); +} +// 1 +// 2 +// 3 +</pre> + +<h3 id="Lặp_qua_một_đối_tượng_arguments">Lặp qua một đối tượng <code>arguments</code></h3> + +<p>Lặp qua đối tượng {{jsxref("Functions/arguments", "arguments")}} để có tất cả giá trị được truyền vào trong hàm:</p> + +<pre class="brush: js notranslate">(function() { + for (const argument of arguments) { + console.log(argument); + } +})(1, 2, 3); + +// 1 +// 2 +// 3</pre> + +<h3 id="Lặp_qua_một_tập_DOM">Lặp qua một tập DOM</h3> + +<p>Lặp qua một tập DOM như {{domxref("NodeList")}}: ví dụ bên dưới, thêm class <code>read</code> cho các đoạn văn bản nào là con trực tiếp của article:</p> + +<pre class="brush:js notranslate">// Lưu ý: Chỉ hoạt động động trên các platforms có +// hiện thực NodeList.prototype[Symbol.iterator] +const articleParagraphs = document.querySelectorAll('article > p'); + +for (const paragraph of articleParagraphs) { + paragraph.classList.add('read'); +} +</pre> + +<h3 id="Đóng_vòng_lặp">Đóng vòng lặp</h3> + +<p>Trong vòng lặp <code>for...of</code>, có thể ngừng lặp giữa chừng bằng <code>break</code>, <code>continue</code>, <code>throw</code> hoặc <code>return</code>. Trong các trường hợp này, vòng lặp sẽ được ngưng lại.</p> + +<pre class="brush: js notranslate">function* foo(){ + yield 1; + yield 2; + yield 3; +}; + +for (const o of foo()) { + console.log(o); + break; // đóng vòng lặp, tiếp tục thực thi bên ngoài vòng lặp +} +console.log('Xong') +</pre> + +<h3 id="Lặp_qua_generator">Lặp qua generator</h3> + +<p>Bạn cũng có thể lặp qua hàm <a href="/en-US/docs/Web/JavaScript/Reference/Statements/function*">generators</a>, ví dụ:</p> + +<pre class="brush:js notranslate">function* fibonacci() { // một hàm generator + let [prev, curr] = [0, 1]; + while (true) { + [prev, curr] = [curr, prev + curr]; + yield curr; + } +} + +for (const n of fibonacci()) { + console.log(n); + // truncate the sequence at 1000 + if (n >= 1000) { + break; + } +} +</pre> + +<h4 id="Không_tái_sử_dụng_generator">Không tái sử dụng generator</h4> + +<p>Không nên re-used Generator, ngay cả khi vòng lặp <code>for...of</code> bị kết thúc sớm bằng {{jsxref("Statements/break", "break")}}. Khi thoát khỏi vòng lặp, generator sẽ kết thúc và cố lặp lại lần nữa sẽ không cho thêm bất kỳ kết quả yield nào khác.</p> + +<pre class="brush: js example-bad notranslate">const gen = (function *(){ + yield 1; + yield 2; + yield 3; +})(); +for (const o of gen) { + console.log(o); + break; // Closes iterator +} + +// Không dùng lại generator, đoạn code như thế này không hợp lý! +for (const o of gen) { + console.log(o); // Không bao giờ được gọi +} +</pre> + +<h3 id="Lặp_qua_các_đối_tượng_khác">Lặp qua các đối tượng khác</h3> + +<p>Bạn cũng có thể loop qua các đối tượng tự định nghĩa, nếu có hiện thực <a href="/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#iterable">iterable</a>:</p> + +<pre class="brush:js notranslate">const iterable = { + [Symbol.iterator]() { + return { + i: 0, + next() { + if (this.i < 3) { + return { value: this.i++, done: false }; + } + return { value: undefined, done: true }; + } + }; + } +}; + +for (const value of iterable) { + console.log(value); +} +// 0 +// 1 +// 2 +</pre> + +<h3 id="Sự_khác_biệt_giữa_for...of_và_for...in">Sự khác biệt giữa <code>for...of</code> và <code>for...in</code></h3> + +<p>Cú pháp {{jsxref("Statements/for...in", "for...in")}} lặp qua các đối tượng <a href="/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties">được đếm</a>, theo một thứ tự tùy ý.</p> + +<p>Cú pháp <code>for...of</code> lặp qua đối tượng dữ liệu <a href="/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterables">có thể lặp</a>.</p> + +<p>Ví dụ sau để thấy sự khác nhau giữa <code>for...of</code> và <code>for...in</code> khi sử dụng với {{jsxref("Array")}}.</p> + +<pre class="brush:js notranslate">Object.prototype.objCustom = function() {}; +Array.prototype.arrCustom = function() {}; + +const iterable = [3, 5, 7]; +iterable.foo = 'hello'; + +for (const i in iterable) { + console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom" +} + +for (const i in iterable) { + if (iterable.hasOwnProperty(i)) { + console.log(i); // logs 0, 1, 2, "foo" + } +} + +for (const i of iterable) { + console.log(i); // logs 3, 5, 7 +} +</pre> + +<p>Giải thích ví dụ trên</p> + +<pre class="brush: js notranslate">Object.prototype.objCustom = function() {}; +Array.prototype.arrCustom = function() {}; + +const iterable = [3, 5, 7]; +iterable.foo = 'hello';</pre> + +<p>Tất cả object sẽ kế thừa thuộc tính <code>objCustom</code> và tất cả {{jsxref("Array")}} sẽ kết thừa thuộc tính <code>arrCustom</code> bởi vì chúng ta thêm nó vào bằng {{jsxref("Object.prototype")}} và {{jsxref("Array.prototype")}}. <code>iterable</code> kế thừa cả <code>objCustom</code> và <code>arrCustom</code>.</p> + +<pre class="brush: js notranslate">for (const i in iterable) { + console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom" +}</pre> + +<p>Vòng vòng lặp này chỉ log <a href="/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties">thuộc tính được đếm</a> của <code>iterable</code>, theo thứ tự được đưa vào. Nó không log các <strong>element</strong> của array <code>3</code>, <code>5</code>, <code>7</code> hoặc <code>hello</code> bởi vì nó là không thuộc tính được đếm. Nó log giá trị <strong>index</strong> cũng như <code>arrCustom</code> và <code>objCustom</code>.</p> + +<pre class="brush: js notranslate">for (let i in iterable) { + if (iterable.hasOwnProperty(i)) { + console.log(i); // logs 0, 1, 2, "foo" + } +}</pre> + +<p>Vòng loop tương tự như ở trên, nhưng sử dụng {{jsxref("Object.prototype.hasOwnProperty()", "hasOwnProperty()")}} để kiểm tra, nếu tìm thấy một property của chính nó chứ không phải kế thừa và log kết quả ra. Các Property <code>0</code>, <code>1</code>, <code>2</code> và <code>foo</code> được log bởi vì nó không phải được kết thừa.</p> + +<pre class="brush: js notranslate">for (const i of iterable) { + console.log(i); // logs 3, 5, 7 +}</pre> + +<p>Vòng lặp và log ra giá trị bên trong đối tượng <code>iterable</code> như một <a href="/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterables">iterable object</a><strong> </strong> được khai báo để lặp, chính là các element bên trong mảng <code>3</code>, <code>5</code>, <code>7</code> và không bao gồm các <strong>property</strong> của object.</p> + +<h2 id="Đặc_điểm">Đặc điểm</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Đặc điểm</th> + <th scope="col">Status</th> + <th scope="col">Ghi chú</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-for-in-and-for-of-statements', 'for...of statement')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-for-in-and-for-of-statements', 'for...of statement')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Trình_duyệt_hổ_trợ">Trình duyệt hổ trợ</h2> + +<div class="hidden">Nếu muốn đóng góp dữ liệu cho bảng này, vui lòng check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> và gởi chúng tôi pull request.</div> + +<p>{{Compat("javascript.statements.for_of")}}</p> + +<h2 id="Xem_thêm">Xem thêm</h2> + +<ul> + <li>{{jsxref("Array.prototype.forEach()")}}</li> + <li>{{jsxref("Map.prototype.forEach()")}}</li> +</ul> diff --git a/files/vi/web/javascript/reference/statements/for/index.html b/files/vi/web/javascript/reference/statements/for/index.html new file mode 100644 index 0000000000..613732de85 --- /dev/null +++ b/files/vi/web/javascript/reference/statements/for/index.html @@ -0,0 +1,137 @@ +--- +title: for +slug: Web/JavaScript/Reference/Statements/for +translation_of: Web/JavaScript/Reference/Statements/for +--- +<div>{{jsSidebar("Statements")}}</div> + +<p>The <strong>for statement</strong> creates a loop that consists of three optional expressions, enclosed in parentheses and separated by semicolons, followed by a statement (usually a <a href="/en-US/docs/Web/JavaScript/Reference/Statements/block">block statement</a>) to be executed in the loop.</p> + +<div>{{EmbedInteractiveExample("pages/js/statement-for.html")}}</div> + + + +<h2 id="Syntax">Syntax</h2> + +<pre class="syntaxbox">for ([<em>initialization</em>]; [<em>condition</em>]; [<em>final-expression</em>]) + <em>statement</em></pre> + +<dl> + <dt><code>initialization</code></dt> + <dd>An expression (including assignment expressions) or variable declaration evaluated once before the loop begins. Typically used to initialize a counter variable. This expression may optionally declare new variables with <code>var</code> or <code>let</code> keywords. Variables declared with <code>var</code> are not local to the loop, i.e. they are in the same scope the <code>for</code> loop is in. Variables declared with let are local to the statement.</dd> + <dd>The result of this expression is discarded.</dd> + <dt><code>condition</code></dt> + <dd>An expression to be evaluated before each loop iteration. If this expression evaluates to true, <code>statement</code> is executed. This conditional test is optional. If omitted, the condition always evaluates to true. If the expression evaluates to false, execution skips to the first expression following the <code>for</code> construct.</dd> + <dt><code>final-expression</code></dt> + <dd>An expression to be evaluated at the end of each loop iteration. This occurs before the next evaluation of <code>condition</code>. Generally used to update or increment the counter variable.</dd> + <dt><code>statement</code></dt> + <dd>A statement that is executed as long as the condition evaluates to true. To execute multiple statements within the loop, use a {{jsxref("Statements/block", "block", "", 0)}} statement (<code>{ ... }</code>) to group those statements. To execute no statement within the loop, use an {{jsxref("Statements/empty", "empty", "", 0)}} statement (<code>;</code>).</dd> +</dl> + +<h2 id="Examples">Examples</h2> + +<h3 id="Using_for">Using <code>for</code></h3> + +<p>The following <code>for</code> statement starts by declaring the variable <code>i</code> and initializing it to <code>0</code>. It checks that <code>i</code> is less than nine, performs the two succeeding statements, and increments <code>i</code> by 1 after each pass through the loop.</p> + +<pre class="brush: js">for (let i = 0; i < 9; i++) { + console.log(i); + // more statements +} +</pre> + +<h3 id="Optional_for_expressions">Optional <code>for</code> expressions</h3> + +<p>All three expressions in the head of the <code>for</code> loop are optional.</p> + +<p>For example, in the <em>initialization</em> block it is not required to initialize variables:</p> + +<pre class="brush: js">var i = 0; +for (; i < 9; i++) { + console.log(i); + // more statements +} +</pre> + +<p>Like the <em>initialization</em> block, the <em>condition</em> block is also optional. If you are omitting this expression, you must make sure to break the loop in the body in order to not create an infinite loop.</p> + +<pre class="brush: js">for (let i = 0;; i++) { + console.log(i); + if (i > 3) break; + // more statements +}</pre> + +<p>You can also omit all three blocks. Again, make sure to use a {{jsxref("Statements/break", "break")}} statement to end the loop and also modify (increase) a variable, so that the condition for the break statement is true at some point.</p> + +<pre class="brush: js">var i = 0; + +for (;;) { + if (i > 3) break; + console.log(i); + i++; +} +</pre> + +<h3 id="Using_for_without_a_statement">Using <code>for</code> without a statement</h3> + +<p>The following <code>for</code> cycle calculates the offset position of a node in the <em>final-expression</em> section, and therefore it does not require the use of a <code>statement</code> section, a semicolon is used instead.</p> + +<pre class="brush: js">function showOffsetPos(sId) { + + var nLeft = 0, nTop = 0; + + for ( + + var oItNode = document.getElementById(sId); /* initialization */ + + oItNode; /* condition */ + + nLeft += oItNode.offsetLeft, nTop += oItNode.offsetTop, oItNode = oItNode.offsetParent /* final-expression */ + + ); /* semicolon */ + + console.log('Offset position of \'' + sId + '\' element:\n left: ' + nLeft + 'px;\n top: ' + nTop + 'px;'); + +} + +/* Example call: */ + +showOffsetPos('content'); + +// Output: +// "Offset position of "content" element: +// left: 0px; +// top: 153px;"</pre> + +<div class="note"><strong>Note:</strong> This is one of the few cases in JavaScript where <strong>the semicolon is mandatory</strong>. Indeed, without the semicolon the line that follows the cycle declaration will be considered a statement.</div> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-for-statement', 'for statement')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<div class="hidden"><font><font>Bảng tương thích trên trang này được tạo từ dữ liệu có cấu trúc. </font><font>Nếu bạn muốn đóng góp cho dữ liệu, vui lòng xem </font></font><a href="https://github.com/mdn/browser-compat-data"><font><font>https://github.com/mdn/browser-compat-data</font></font></a><font><font> và gửi cho chúng tôi yêu cầu kéo.</font></font></div> + +<p><font><font>{{Compat ("javascript.statements.for")}}</font></font></p> + +<h2 id="Xem_thêm"><font><font>Xem thêm</font></font></h2> + +<ul> + <li><font><font>{{jsxref ("Báo cáo / trống", "tuyên bố trống", "", 0)}}</font></font></li> + <li><font><font>{{jsxref ("Tuyên bố / phá vỡ", "phá vỡ")}}</font></font></li> + <li><font><font>{{jsxref ("Tuyên bố / tiếp tục", "tiếp tục")}}</font></font></li> + <li><font><font>{{jsxref ("Tuyên bố / while", "while")}}</font></font></li> + <li><font><font>{{jsxref ("Tuyên bố / làm ... trong khi", "làm ... trong khi")}}</font></font></li> + <li><font><font>{{jsxref ("Tuyên bố / cho ... trong", "cho ... trong")}}</font></font></li> + <li><font><font>{{jsxref ("Tuyên bố / cho ... của", "cho ... của")}}</font></font></li> +</ul> diff --git a/files/vi/web/javascript/reference/statements/function_star_/index.html b/files/vi/web/javascript/reference/statements/function_star_/index.html new file mode 100644 index 0000000000..388e0f8b34 --- /dev/null +++ b/files/vi/web/javascript/reference/statements/function_star_/index.html @@ -0,0 +1,208 @@ +--- +title: function* +slug: Web/JavaScript/Reference/Statements/function* +translation_of: Web/JavaScript/Reference/Statements/function* +--- +<div>{{jsSidebar("Statements")}}</div> + +<p>Khai báo <code><strong>function*</strong></code> (từ khóa <code>function</code> tiếp theo là dấu sao) định nghĩa một <em>generator function</em>, một phương thức trả về đối tượng {{jsxref("Global_Objects/Generator","Generator")}}.</p> + +<div>{{EmbedInteractiveExample("pages/js/statement-functionasterisk.html")}}</div> + + + +<div class="noinclude"> +<p>Bạn cũng có thể khai báo generator functions bằng constructor {{jsxref("GeneratorFunction")}} , hoặc cú pháp function expression.</p> +</div> + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox notranslate">function* <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) { + <em>statements</em> +} +</pre> + +<dl> + <dt><code>name</code></dt> + <dd>Tên phương thức</dd> +</dl> + +<dl> + <dt><code>param</code></dt> + <dd>Các tham số truyền vào cho phương thức.</dd> +</dl> + +<dl> + <dt><code>statements</code></dt> + <dd>Các câu lệnh bên trong phương thức</dd> +</dl> + +<h2 id="Diễn_giải">Diễn giải</h2> + +<p>Generators là một hàm có thể thoát và sau đó gọi lại lần nữa. Giá trị của biến trong các lần gọi được lưu lại trong các lần gọi tiếp theo.<br> + <br> + Pattern là cách hàm <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function">async</a></code> được viết ra.</p> + +<p>Gọi một generator function không thực thi các lệnh bên trong hàm ngày lập tức; Thay vào đó, một object <a href="/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#iterator">iterator</a> được trả về. Khi iterator gọi đến phương thức <code>next()</code> , lúc này các lệnh bên trong hàm được thực thi cho đến khi gặp câu {{jsxref("Operators/yield", "yield")}} , sau câu lệnh {{jsxref("Operators/yield", "yield")}} là giá trị sẽ trả về, hoặc gọi đến một generator function khác. Phương thức <code>next()</code> trả về một object với property <code>value</code> chứa giá trị yielded và property <code>done</code> , giá trị kiểu boolean, xác định generator yielded trả về đã là cuối cùng chưa. Gọi phương thức <code>next()</code> với một tham số sẽ chạy hàm generator tiếp tục, thay thế câu <code>yield</code> nơi hàm đã dừng lại trước đó với tham số từ <code>next()</code>. </p> + +<p>Câu lệnh <code>return</code> trong generator, khi chạy, sẽ kết thúc generator (ví dụ property <code>done</code> trả về sẽ có giá trị <code>true</code>). Nếu giá trị đã được trả về, nó sẽ được set cho property <code>value</code>.<br> + Giống như câu lệnh <code>return</code> , thrown error trong generator sẽ kết thúc generator -- trừ khi bắt lại bằng bên trong generator.<br> + Khi một generator kết thúc, các câu gọi <code>next</code> tiếp theo sau sẽ không được thực thi, nó chỉ trả về object có dạng: <code>{value: undefined, done: true}</code>.</p> + +<h2 id="Ví_dụ">Ví dụ</h2> + +<h3 id="Ví_dụ_đơn_giản">Ví dụ đơn giản</h3> + +<pre class="brush: js notranslate">function* idMaker() { + var index = 0; + while (index < index+1) + yield index++; +} + +var gen = idMaker(); + +console.log(gen.next().value); // 0 +console.log(gen.next().value); // 1 +console.log(gen.next().value); // 2 +console.log(gen.next().value); // 3 +// ...</pre> + +<h3 id="Ví_dụ_với_yield*">Ví dụ với yield*</h3> + +<pre class="brush: js notranslate">function* anotherGenerator(i) { + yield i + 1; + yield i + 2; + yield i + 3; +} + +function* generator(i) { + yield i; + yield* anotherGenerator(i); + yield i + 10; +} + +var gen = generator(10); + +console.log(gen.next().value); // 10 +console.log(gen.next().value); // 11 +console.log(gen.next().value); // 12 +console.log(gen.next().value); // 13 +console.log(gen.next().value); // 20 +</pre> + +<h3 id="Truyền_tham_số_vào_trong_Generators">Truyền tham số vào trong Generators</h3> + +<pre class="brush: js notranslate">function* logGenerator() { + console.log(0); + console.log(1, yield); + console.log(2, yield); + console.log(3, yield); +} + +var gen = logGenerator(); + +gen.next(); // 0 +gen.next('pretzel'); // 1 pretzel +gen.next('california'); // 2 california +gen.next('mayonnaise'); // 3 mayonnaise +</pre> + +<h3 id="Return_bên_trong_generator">Return bên trong generator</h3> + +<pre class="brush: js notranslate">function* yieldAndReturn() { + yield "Y"; + return "R"; + yield "unreachable"; +} + +var gen = yieldAndReturn() +console.log(gen.next()); // { value: "Y", done: false } +console.log(gen.next()); // { value: "R", done: true } +console.log(gen.next()); // { value: undefined, done: true } +</pre> + +<h3 id="Generators_không_dùng_constructable">Generators không dùng constructable</h3> + +<pre class="brush: js notranslate">function* f() {} +var obj = new f; // throws "TypeError: f is not a constructor +</pre> + +<h3 id="Generator_khai_báo_bằng_expression">Generator khai báo bằng expression</h3> + +<pre class="brush: js notranslate">const foo = function* () { + yield 10; + yield 20; +}; + +const bar = foo(); +console.log(bar.next()); // {value: 10, done: false}</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ES2015', '#sec-generator-function-definitions', 'function*')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ES2016', '#sec-generator-function-definitions', 'function*')}}</td> + <td>{{Spec2('ES2016')}}</td> + <td>Changed that generators should not have [[Construct]] trap and will throw when used with <code>new</code>.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-generator-function-definitions', 'function*')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Trình_duyệt_hỗ_trợ">Trình duyệt hỗ trợ</h2> + +<div> + + +<p>{{Compat("javascript.statements.generator_function")}}</p> +</div> + +<h2 id="Lưu_ý_dành_riêng_cho_Firefox">Lưu ý dành riêng cho Firefox</h2> + +<h4 id="Generators_và_iterators_trước_phiên_bản_Firefox_26">Generators và iterators trước phiên bản Firefox 26</h4> + +<p>Older Firefox versions implement an older version of the generators proposal. In the older version, generators were defined using a regular <code>function</code> keyword (without an asterisk) among other differences. See <a href="/en-US/docs/Web/JavaScript/Reference/Statements/Legacy_generator_function">Legacy generator function </a>for further information.</p> + +<h4 id="IteratorResult_object_returned_instead_of_throwing"><code>IteratorResult</code> object returned instead of throwing</h4> + +<p>Starting with Gecko 29 {{geckoRelease(29)}}, the completed generator function no longer throws a {{jsxref("TypeError")}} "generator has already finished". Instead, it returns an <code>IteratorResult</code> object like <code>{ value: undefined, done: true }</code> ({{bug(958951)}}).</p> + +<h2 id="Xem_thêm">Xem thêm</h2> + +<ul> + <li>{{jsxref("Operators/function*", "function* expression")}}</li> + <li>{{jsxref("GeneratorFunction")}} object</li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Iteration_protocols">Iteration protocols</a></li> + <li>{{jsxref("Operators/yield", "yield")}}</li> + <li>{{jsxref("Operators/yield*", "yield*")}}</li> + <li>{{jsxref("Function")}} object</li> + <li>{{jsxref("Statements/function", "function declaration")}}</li> + <li>{{jsxref("Operators/function", "function expression")}}</li> + <li>{{jsxref("Functions_and_function_scope", "Functions and function scope")}}</li> + <li>Nguồn trang khác: + <ul> + <li><a href="http://facebook.github.io/regenerator/">Regenerator</a> an ES2015 generator compiler to ES5</li> + <li><a href="http://www.youtube.com/watch?v=qbKWsbJ76-s">Forbes Lindesay: Promises and Generators: control flow utopia -- JSConf EU 2013</a></li> + <li><a href="https://www.youtube.com/watch?v=ZrgEZykBHVo&list=PLuoyIZT5fPlG44bPq50Wgh0INxykdrYX7&index=1">Hemanth.HM: The New gen of *gen(){}</a></li> + <li><a href="https://github.com/mozilla/task.js">Task.js</a></li> + <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/master/async%20%26%20performance/ch4.md#iterating-generators-asynchronously">Iterating generators asynchronously</a></li> + </ul> + </li> +</ul> diff --git a/files/vi/web/javascript/reference/statements/index.html b/files/vi/web/javascript/reference/statements/index.html new file mode 100644 index 0000000000..460884b7d9 --- /dev/null +++ b/files/vi/web/javascript/reference/statements/index.html @@ -0,0 +1,143 @@ +--- +title: Statements and declarations +slug: Web/JavaScript/Reference/Statements +tags: + - JavaScript + - NeedsTranslation + - Reference + - TopicStub + - statements +translation_of: Web/JavaScript/Reference/Statements +--- +<div>{{jsSidebar("Statements")}}</div> + +<p>JavaScript applications consist of statements with an appropriate syntax. A single statement may span multiple lines. Multiple statements may occur on a single line if each statement is separated by a semicolon. This isn't a keyword, but a group of keywords.</p> + +<h2 id="Statements_and_declarations_by_category">Statements and declarations by category</h2> + +<p>For an alphabetical listing see the sidebar on the left.</p> + +<h3 id="Control_flow">Control flow</h3> + +<dl> + <dt>{{jsxref("Statements/block", "Block")}}</dt> + <dd>A block statement is used to group zero or more statements. The block is delimited by a pair of curly brackets.</dd> + <dt>{{jsxref("Statements/break", "break")}}</dt> + <dd>Terminates the current loop, switch, or label statement and transfers program control to the statement following the terminated statement.</dd> + <dt>{{jsxref("Statements/continue", "continue")}}</dt> + <dd>Terminates execution of the statements in the current iteration of the current or labeled loop, and continues execution of the loop with the next iteration.</dd> + <dt>{{jsxref("Statements/Empty", "Empty")}}</dt> + <dd>An empty statement is used to provide no statement, although the JavaScript syntax would expect one.</dd> + <dt>{{jsxref("Statements/if...else", "if...else")}}</dt> + <dd>Executes a statement if a specified condition is true. If the condition is false, another statement can be executed.</dd> + <dt>{{jsxref("Statements/switch", "switch")}}</dt> + <dd>Evaluates an expression, matching the expression's value to a case clause, and executes statements associated with that case.</dd> + <dt>{{jsxref("Statements/throw", "throw")}}</dt> + <dd>Throws a user-defined exception.</dd> + <dt>{{jsxref("Statements/try...catch", "try...catch")}}</dt> + <dd>Marks a block of statements to try, and specifies a response, should an exception be thrown.</dd> +</dl> + +<h3 id="Declarations">Declarations</h3> + +<dl> + <dt>{{jsxref("Statements/var", "var")}}</dt> + <dd>Declares a variable, optionally initializing it to a value.</dd> + <dt>{{jsxref("Statements/let", "let")}}</dt> + <dd>Declares a block scope local variable, optionally initializing it to a value.</dd> + <dt>{{jsxref("Statements/const", "const")}}</dt> + <dd>Declares a read-only named constant.</dd> +</dl> + +<h3 id="Functions_and_classes">Functions and classes</h3> + +<dl> + <dt>{{jsxref("Statements/function", "function")}}</dt> + <dd>Declares a function with the specified parameters.</dd> + <dt>{{jsxref("Statements/function*", "function*")}}</dt> + <dd>Generators functions enable writing <a href="/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol">iterators</a> more easily.</dd> + <dt>{{jsxref("Statements/async_function", "async function")}}</dt> + <dd>Declares an async function with the specified parameters.</dd> + <dt>{{jsxref("Statements/return", "return")}}</dt> + <dd>Specifies the value to be returned by a function.</dd> + <dt>{{jsxref("Statements/class", "class")}}</dt> + <dd>Declares a class.</dd> +</dl> + +<h3 id="Iterations">Iterations</h3> + +<dl> + <dt>{{jsxref("Statements/do...while", "do...while")}}</dt> + <dd>Creates a loop that executes a specified statement until the test condition evaluates to false. The condition is evaluated after executing the statement, resulting in the specified statement executing at least once.</dd> + <dt>{{jsxref("Statements/for", "for")}}</dt> + <dd>Creates a loop that consists of three optional expressions, enclosed in parentheses and separated by semicolons, followed by a statement executed in the loop.</dd> + <dt>{{deprecated_inline}} {{non-standard_inline()}} {{jsxref("Statements/for_each...in", "for each...in")}}</dt> + <dd>Iterates a specified variable over all values of object's properties. For each distinct property, a specified statement is executed.</dd> + <dt>{{jsxref("Statements/for...in", "for...in")}}</dt> + <dd>Iterates over the enumerable properties of an object, in arbitrary order. For each distinct property, statements can be executed.</dd> + <dt>{{jsxref("Statements/for...of", "for...of")}}</dt> + <dd>Iterates over iterable objects (including {{jsxref("Global_Objects/Array","arrays","","true")}}, array-like objects, <a href="/en-US/docs/JavaScript/Guide/Iterators_and_Generators">iterators and generators</a>), invoking a custom iteration hook with statements to be executed for the value of each distinct property.</dd> + <dt>{{jsxref("Statements/while", "while")}}</dt> + <dd>Creates a loop that executes a specified statement as long as the test condition evaluates to true. The condition is evaluated before executing the statement.</dd> +</dl> + +<h3 id="Others">Others</h3> + +<dl> + <dt>{{jsxref("Statements/debugger", "debugger")}}</dt> + <dd>Invokes any available debugging functionality. If no debugging functionality is available, this statement has no effect.</dd> + <dt>{{jsxref("Statements/export", "export")}}</dt> + <dd>Used to export functions to make them available for imports in external modules, another scripts.</dd> + <dt>{{jsxref("Statements/import", "import")}}</dt> + <dd>Used to import functions exported from an external module, another script.</dd> + <dt>{{jsxref("Statements/label", "label")}}</dt> + <dd>Provides a statement with an identifier that you can refer to using a <code>break</code> or <code>continue</code> statement.</dd> +</dl> + +<dl> + <dt>{{deprecated_inline}} {{jsxref("Statements/with", "with")}}</dt> + <dd>Extends the scope chain for a statement.</dd> +</dl> + +<h2 id="Specifications">Specifications</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('ES1', '#sec-12', 'Statements')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition</td> + </tr> + <tr> + <td>{{SpecName('ES3', '#sec-12', 'Statements')}}</td> + <td>{{Spec2('ES3')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-12', 'Statements')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-ecmascript-language-statements-and-declarations', 'ECMAScript Language: Statements and Declarations')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>New: function*, let, for...of, yield, class</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-ecmascript-language-statements-and-declarations', 'ECMAScript Language: Statements and Declarations')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators">Operators</a></li> +</ul> diff --git a/files/vi/web/javascript/reference/statements/throw/index.html b/files/vi/web/javascript/reference/statements/throw/index.html new file mode 100644 index 0000000000..c3116c8847 --- /dev/null +++ b/files/vi/web/javascript/reference/statements/throw/index.html @@ -0,0 +1,193 @@ +--- +title: throw +slug: Web/JavaScript/Reference/Statements/throw +translation_of: Web/JavaScript/Reference/Statements/throw +--- +<div>{{jsSidebar("Statements")}}</div> + +<p>Câu lệnh <strong><code>throw</code> </strong> sẽ đưa ra một exception theo cách chúng ta định nghĩa. Các câu lệnh phía sau <code>throw</code> sẽ không được chạy, và sẽ gọi hàm callback <a href="/en-US/docs/Web/JavaScript/Reference/Statements/try...catch"><code>catch</code></a> đầu tiên tìm thấy. Nếu không có hàm <code>catch</code>, chương trình sẽ không chạy nữa.</p> + +<div>{{EmbedInteractiveExample("pages/js/statement-throw.html")}}</div> + +<p class="hidden">Source này được lưu trên GitHub repository. Nếu muốn đóng góp cho ví dụ này, bạn clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> và gởi lên pull request.</p> + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox">throw <em>expression</em>; </pre> + +<dl> + <dt><code>expression</code></dt> + <dd>Một diễn giải.</dd> +</dl> + +<h2 id="Giải_thích">Giải thích</h2> + +<p>Sử dụng câu lệnh <code>throw</code> để đưa ra một exception. Giá trị của expression trả về có thể string, number, boolean, hay Object. Mỗi câu <code>throw </code>chỉ trả về một exception</p> + +<pre class="brush: js">throw 'Error2'; // 1 exception dạng string +throw 42; // 1 exception giá trị 42 +throw true; // 1 exception với giá trị boolean là true +throw new Error('Required'); // tạo một error object với nội dung Required +</pre> + +<p>Câu lệnh <code>throw</code> tuân thủ nguyên tắc <a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Automatic_semicolon_insertion">automatic semicolon insertion (ASI)</a> , nghĩa là không được phép xuống dòng giữa từ khóa <code>throw</code> và <code>expression</code>.</p> + +<h2 id="Ví_dụ">Ví dụ</h2> + +<h3 id="Throw_một_object">Throw một object</h3> + +<p>Exception có thể là một object. Lúc này có thể tham chiếu đến các property của object bên trong khối lệnh <code>catch</code> . Ví dụ sau, tạo một object với kiểu là <code>UserException</code> và sử dụng nó trong câu <code>throw</code>.</p> + +<pre class="brush: js">function UserException(message) { + this.message = message; + this.name = 'UserException'; +} +function getMonthName(mo) { + mo = mo - 1; // Thay đổi giá trị của index array tương ứng cho tháng (1 = Jan, 12 = Dec) + var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', + 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + if (months[mo] !== undefined) { + return months[mo]; + } else { + throw new UserException('InvalidMonthNo'); + } +} + +try { + // statements to try + var myMonth = 15; // 15 nằm ngoài giá trị cho phép + var monthName = getMonthName(myMonth); +} catch (e) { + monthName = 'unknown'; + console.log(e.message, e.name); // truyền exception object vào câu lệnh xử lý nếu có lỗi +} +</pre> + +<h3 id="Một_ví_dụ_khác_sử_dụng_object">Một ví dụ khác sử dụng object</h3> + +<p>Trong ví dụ sau, kiểm tra input, chỉ cho phép là giá trị U.S. zip code. Nếu giá trị zip code này không đúng format, throw một exception object là <code>ZipCodeFormatException</code>.</p> + +<pre class="brush: js">/* + * Creates a ZipCode object. + * + * Accepted formats for a zip code are: + * 12345 + * 12345-6789 + * 123456789 + * 12345 6789 + * + * If the argument passed to the ZipCode constructor does not + * conform to one of these patterns, an exception is thrown. + */ + +function ZipCode(zip) { + zip = new String(zip); + pattern = /[0-9]{5}([- ]?[0-9]{4})?/; + if (pattern.test(zip)) { + // giá trị zip code value sẽ là giá trị đầu tiên khớp trong string + this.value = zip.match(pattern)[0]; + this.valueOf = function() { + return this.value + }; + this.toString = function() { + return String(this.value) + }; + } else { + throw new ZipCodeFormatException(zip); + } +} + +function ZipCodeFormatException(value) { + this.value = value; + this.message = 'does not conform to the expected format for a zip code'; + this.toString = function() { + return this.value + this.message; + }; +} + +/* + * Đoạn script validate address theo kiểu US addresses. + */ + +const ZIPCODE_INVALID = -1; +const ZIPCODE_UNKNOWN_ERROR = -2; + +function verifyZipCode(z) { + try { + z = new ZipCode(z); + } catch (e) { + if (e instanceof ZipCodeFormatException) { + return ZIPCODE_INVALID; + } else { + return ZIPCODE_UNKNOWN_ERROR; + } + } + return z; +} + +a = verifyZipCode(95060); // returns 95060 +b = verifyZipCode(9560); // returns -1 +c = verifyZipCode('a'); // returns -1 +d = verifyZipCode('95060'); // returns 95060 +e = verifyZipCode('95060 1234'); // returns 95060 1234 +</pre> + +<h3 id="Rethrow_một_exception">Rethrow một exception</h3> + +<p>Chúng ta có thể sử dụng <code>throw</code> để rethrow một exception sau khi đã catch nó. Trong ví dụ sau, catch lại exception nếu là giá trị lớn hơn 50 thì rethrow. Exception này sẽ được đưa lên hàm trên một cấp hoặc lên trên cùng cho các hàm catch khác.</p> + +<pre class="brush: js">try { + throw n; // throws một exception với giá trị là số +} catch (e) { + if (e <= 50) { + // câu lệnh xử lý cho exception từ 1-50 + } else { + // không có xử lý cho trường hợp exception này, rethrow + throw e; + } +} +</pre> + +<h2 id="Specification">Specification</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('ES3')}}</td> + <td>{{Spec2('ES3')}}</td> + <td>Khởi tạo. Hiện thực trong JavaScript 1.4</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-12.13', 'throw statement')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-throw-statement', 'throw statement')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-throw-statement', 'throw statement')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Trình_duyệt_hổ_trợ">Trình duyệt hổ trợ</h2> + + + +<p>{{Compat("javascript.statements.throw")}}</p> + +<h2 id="Xem_thêm">Xem thêm</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/try...catch"><code>try...catch</code></a></li> +</ul> |