diff options
Diffstat (limited to 'files/vi/web/javascript/reference/operators')
9 files changed, 2552 insertions, 0 deletions
diff --git a/files/vi/web/javascript/reference/operators/arithmetic_operators/index.html b/files/vi/web/javascript/reference/operators/arithmetic_operators/index.html new file mode 100644 index 0000000000..a9fe805490 --- /dev/null +++ b/files/vi/web/javascript/reference/operators/arithmetic_operators/index.html @@ -0,0 +1,312 @@ +--- +title: Toán tử số học +slug: Web/JavaScript/Reference/Operators/Arithmetic_Operators +translation_of: Web/JavaScript/Reference/Operators +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><strong>Toán tử số học</strong> lấy giá trị số học (cả chuỗi hoặc biến) làm toán hạng của nó và trả về một giá trị số học. Các toán tử số học thông thường là cộng (+), trừ (-), nhân (*), và chia (/).</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-arithmetic.html")}}</div> + +<p class="hidden">Mã nguồn cho các ví dụ tương tác trong bài được lưu trên GitHub. Nếu bạn muốn đóng góp thêm ví dụ tương tác, làm ơn <em>clone</em> lại <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> và gửi cho chúng tôi một <em>pull request</em>.</p> + +<h2 id="Cộng_()"><a name="Addition">Cộng (+)</a></h2> + +<p>Toán tử cộng xuất ra tổng của toán hạng số học hoặc để nối chuỗi.</p> + +<h3 id="Cú_pháp">Cú pháp</h3> + +<pre class="syntaxbox"><strong>Toán tử:</strong> x + y +</pre> + +<h3 id="Examples">Examples</h3> + +<pre class="brush: js">// Number + Number -> addition +1 + 2 // 3 + +// Boolean + Number -> addition +true + 1 // 2 + +// Boolean + Boolean -> addition +false + false // 0 + +// Number + String -> concatenation +5 + 'foo' // "5foo" + +// String + Boolean -> concatenation +'foo' + false // "foofalse" + +// String + String -> concatenation +'foo' + 'bar' // "foobar" +</pre> + +<h2 id="Trừ_(-)"><a name="Subtraction">Trừ (-)</a></h2> + +<p>Toán tử trừ thực hiện trừ hai toán hạng, xuất ra chênh lệch giữa chúng.</p> + +<h3 id="Cú_pháp_2">Cú pháp</h3> + +<pre class="syntaxbox"><strong>Toán tử:</strong> x - y +</pre> + +<h3 id="Ví_dụ">Ví dụ</h3> + +<pre class="brush: js">5 - 3 // 2 +3 - 5 // -2 +'foo' - 3 // NaN</pre> + +<h2 id="Chia_()"><a name="Division">Chia (/)</a></h2> + +<p>Toán tử chia xuất ra thương của phép chia với toán hạng bên trái là số bị chia và toán hạng bên phải là số chia.</p> + +<h3 id="Cú_pháp_3">Cú pháp</h3> + +<pre class="syntaxbox"><strong>Toán tử:</strong> x / y +</pre> + +<h3 id="Ví_dụ_2">Ví dụ</h3> + +<pre class="brush: js">1 / 2 // trả về 0.5 trong JavaScript +1 / 2 // trả về 0 trong Java +// (neither number is explicitly a floating point number) + +1.0 / 2.0 // ?trả về 0.5 trong cả JavaScript lẫn Java + +2.0 / 0 // ?trả về Infinity trong JavaScript +2.0 / 0.0 // cũng trả về Infinity +2.0 / -0.0 // trả về -Infinity trong JavaScript</pre> + +<h2 id="Nhân_(*)"><a name="Multiplication">Nhân (*)</a></h2> + +<p>Toán tử nhân xuất ra tích của các toán hạng.</p> + +<h3 id="Cú_pháp_4">Cú pháp</h3> + +<pre class="syntaxbox"><strong>Toán tử:</strong> x * y +</pre> + +<h3 id="Ví_dụ_3">Ví dụ</h3> + +<pre class="brush: js">2 * 2 // 4 +-2 * 2 // -4 +Infinity * 0 // NaN +Infinity * Infinity // Infinity +'foo' * 2 // NaN +</pre> + +<h2 id="Chia_lấy_dư_()"><a name="Remainder">Chia lấy dư (%)</a></h2> + +<p>Toán tử chia lấy dư trả về phần dư khi toán hạng thứ nhất chia cho toán hạng thứ hai. Dấu của kết quả luôn cùng dấu với số bị chia.</p> + +<h3 id="Cú_pháp_5">Cú pháp</h3> + +<pre class="syntaxbox"><strong>Toán tử:</strong> var1 % var2 +</pre> + +<h3 id="Ví_dụ_4">Ví dụ</h3> + +<pre class="brush: js">12 % 5 // 2 +-1 % 2 // -1 +1 % -2 // 1 +NaN % 2 // NaN +1 % 2 // 1 +2 % 3 // 2 +-4 % 2 // -0 +5.5 % 2 // 1.5 +</pre> + +<h2 id="Luỹ_thừa_(**)"><a name="Exponentiation">Luỹ thừa (**)</a></h2> + +<p>Toán tử luỹ thừa trả về kết quả là luỹ thừa bậc là toán hạng thứ hai của toán hạng thứ nhất, tức là, <code>var1</code><sup><code>var2</code></sup>, như đã khẳng định trước đó, với <code>var1</code> và <code>var2</code> là biến số. Toán tử luỹ thừa là dạng liên hợp phải. <code>a ** b ** c</code> bằng với <code>a ** (b ** c)</code>.</p> + +<h3 id="Cú_pháp_6">Cú pháp</h3> + +<pre class="syntaxbox"><strong>Toán tử:</strong> var1 ** var2 +</pre> + +<h3 id="Ghi_chú">Ghi chú</h3> + +<p>Trong hầu hết các ngôn ngữ như PHP và Python và một số khác mà có toán tử luỹ thừa (**), toán tử luỹ thừa được định nghĩa là có độ ưu tiên cao hơn toán tử một ngôi như là toán tử + một ngôi và toán tử - một ngôi, nhưng cũng có vài ngoại lệ. Chẳng hạn, trong Bash, toán tử ** được định nghĩa là có độ ưu tiên thấp hơn toán tử một ngôi. Trong JavaScript, hoàn toàn có thể viết một biểu thức luỹ thừa nhập nhằng, như là bạn không thể đặt toán tử một ngôi (<code>+/-/~/!/delete/void/typeof</code>) ngay trước cơ số.</p> + +<pre class="brush: js">-2 ** 2; +// 4 trong Bash, -4 trong các ngôn ngữ khác. +// Không hợp lệ trong JavaScript, vì toán tử không nhập nhằng. + + +-(2 ** 2); +// -4 trong JavaScript và ý định của tác giả không nhập nhằng. +</pre> + +<h3 id="Ví_dụ_5">Ví dụ</h3> + +<pre class="brush: js">2 ** 3 // 8 +3 ** 2 // 9 +3 ** 2.5 // 15.588457268119896 +10 ** -1 // 0.1 +NaN ** 2 // NaN + +2 ** 3 ** 2 // 512 +2 ** (3 ** 2) // 512 +(2 ** 3) ** 2 // 64 +</pre> + +<p>To invert the sign of the result of an exponentiation expression:</p> + +<pre class="brush: js">-(2 ** 2) // -4 +</pre> + +<p>Để ép cơ số trong biểu thức luỹ thừa thành số âm:</p> + +<pre class="brush: js">(-2) ** 2 // 4 +</pre> + +<div class="note"> +<p><strong>Ghi chú:</strong> JavaScript cũng có <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_XOR"> toán tử thao tác bit ^ (XOR)</a>. <code>**</code> và <code>^</code> khác nhau (chẳng hạn: <code>2 ** 3 === 8</code> trong khi <code>2 ^ 3 === 1</code>.)</p> +</div> + +<p> </p> + +<h2 id="Tăng_()"><a name="Increment">Tăng (++)</a></h2> + +<p> </p> + +<p>Toán tử tăng tăng (thêm một vào) toán hạng của nó và trả về một giá trị.</p> + +<ul> + <li>Nếu dùng như hậu tố, toán tử ở sau toán hạng (chẳng hạn, x++), thí nó trả về giá trị trước khi tăng.</li> + <li>Nếu dùng như tiền tố, toán tử ở trước toán hạng (chẳng hạn, ++x), thí nó trả về giá trị sau khi tăng.</li> +</ul> + +<h3 id="Cú_pháp_7">Cú pháp</h3> + +<pre class="syntaxbox"><strong>Toán tử:</strong> x++ hoặc ++x +</pre> + +<h3 id="Ví_dụ_6">Ví dụ</h3> + +<pre class="brush: js">// Hậu tố +var x = 3; +y = x++; // y = 3, x = 4 + +// Tiền tố +var a = 2; +b = ++a; // a = 3, b = 3 +</pre> + +<h2 id="Giảm_(--)"><a name="Decrement">Giảm (--)</a></h2> + +<p>Toán tử giảm giảm (bớt một khỏi) toán hạng của nó và trả về một giá trị.</p> + +<ul> + <li>Nếu dùng như hậu tố (chẳng hạn, x--), thì nó trả về giá trị trước khi giảm.</li> + <li>Nếu dùng như tiền tố (chẳng hạn, --x), thì nó trả về giá trị sau khi giảm.</li> +</ul> + +<h3 id="Cú_pháp_8">Cú pháp</h3> + +<pre class="syntaxbox"><strong>Toán tử:</strong> x-- hoặc --x +</pre> + +<h3 id="Ví_dụ_7">Ví dụ</h3> + +<pre class="brush: js">// Hậu tố +var x = 3; +y = x--; // y = 3, x = 2 + +// Tiền tố +var a = 2; +b = --a; // a = 1, b = 1 +</pre> + +<h2 id="Phủ_định_một_ngôi_(-)"><a name="Unary_negation">Phủ định một ngôi (-)</a></h2> + +<p>Toán tử phủ định một ngôi đứng trước và phủ định toán hạng của nó.</p> + +<h3 id="Cú_pháp_9">Cú pháp</h3> + +<pre class="syntaxbox"><strong>Toán tử:</strong> -x +</pre> + +<h3 id="Ví_dụ_8">Ví dụ</h3> + +<pre class="brush: js">var x = 3; +y = -x; // y = -3, x = 3 + +//toán tử phủ định một ngôi có thể chuyển giá-trị-không-phải-kiểu-số về dạng số học +var x = "4"; +y = -x; // y = -4 +</pre> + +<h2 id="Cộng_một_ngôi_()"><a name="Unary_plus">Cộng một ngôi (+)</a></h2> + +<p>Toán tử cộng một ngôi đứng trước và định lượng toán hạng của nó nhưng cố gắng chuyển kiểu cho toán hạng sang dạng số, nếu ban đầu không phải ở dạng đó. Mặc dù toán tử phủ định một ngôi (-) cũng có thể chuyển kiểu như vậy, nhưng toán tử cộng một ngôi lại nhanh nhất và được dùng ưu tiên dùng nhiều hơn khi phải chuyển đổi kiểu dữ liệu về dạng số, bởi vì nó không thực hiện bất cứ phép toán nào khác trên số. Nó có thể chuyển kiểu từ biểu diễn dạng chuỗi của số nguyên hoặc số thực, thậm chí cả các giá trị không phải số như <code>true</code>, <code>false</code>, và <code>null</code>. Số thực ở dạng thập phân và bát phân (tiền tố - "0x") đều được hỗ trợ. Đồng thời hỗ trợ cả số âm (trừ số âm dạng bát phân). Nếu nó không thể truyền đúng dữ liệu đã định, nó sẽ định lượng thành <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN">NaN</a>.</p> + +<h3 id="Cú_pháp_10">Cú pháp</h3> + +<pre class="syntaxbox"><strong>Toán tử:</strong> +x +</pre> + +<h3 id="Ví_dụ_9">Ví dụ</h3> + +<pre class="brush: js">+3 // 3 ++'3' // 3 ++true // 1 ++false // 0 ++null // 0 ++function(val){ return val } // NaN +</pre> + +<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">Bình luận</th> + </tr> + <tr> + <td>{{SpecName('ES1')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.3')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.6">Additive operators</a>, <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.5">Multiplicative operators</a>, <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.3">Postfix expressions</a>, <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.4">Unary operators</a>.</td> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-postfix-expressions')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-additive-operators">Additive operators</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-multiplicative-operators">Multiplicative operators</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-postfix-expressions">Postfix expressions</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-unary-operators">Unary operators</a>.</td> + </tr> + <tr> + <td>{{SpecName('ES2016', '#sec-postfix-expressions')}}</td> + <td>{{Spec2('ES2016')}}</td> + <td>Added <a href="https://github.com/rwaldron/exponentiation-operator">Exponentiation operator</a>.</td> + </tr> + <tr> + <td>{{SpecName('ES2017', '#sec-postfix-expressions')}}</td> + <td>{{Spec2('ES2017')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-additive-operators')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Tương_thích_trình_duyệt">Tương thích trình duyệt</h2> + + + +<p>{{Compat("javascript.operators.arithmetic")}}</p> + +<h2 id="Đọc_thêm">Đọc thêm</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators">Toán tử gán</a></li> +</ul> diff --git a/files/vi/web/javascript/reference/operators/conditional_operator/index.html b/files/vi/web/javascript/reference/operators/conditional_operator/index.html new file mode 100644 index 0000000000..62cc4cadb5 --- /dev/null +++ b/files/vi/web/javascript/reference/operators/conditional_operator/index.html @@ -0,0 +1,119 @@ +--- +title: Conditional (ternary) operator +slug: Web/JavaScript/Reference/Operators/Conditional_Operator +translation_of: Web/JavaScript/Reference/Operators/Conditional_Operator +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><strong>Toán tử điều kiện (ba ngôi)</strong> là toán tử duy nhất của JavaScript cần tới ba toán hạng. Toán tử này thường dùng tắt cho câu lệnh <a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else"><code>if</code></a>.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-conditionaloperators.html")}}</div> + + + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox"><em>condition</em> ? <em>exprT</em> : <em>exprF</em> </pre> + +<h3 id="Tham_số">Tham số</h3> + +<dl> + <dt><code>condition</code></dt> + <dd>Biểu thức mà giá trị của nó được dùng như điều kiện.</dd> +</dl> + +<dl> + <dt><code>exprT</code>, <code>exprF</code></dt> + <dd>Biểu thức với giá trị có kiểu bất kỳ.</dd> +</dl> + +<h2 id="Mô_tả">Mô tả</h2> + +<p>Nếu <code>condition</code> có thể chuyển đổi thành<code>true</code> (hay là {{Glossary("truthy")}}), toán tử trả về giá trị của <code>exprT</code>; ngược lại (khi <code>condition</code> là {{Glossary("falsy")}}), nó trả về giá trị của <code>exprF</code>.</p> + +<p>(Trong cả hai trường hợp, biểu thức còn lại đều không được duyệt tới.)</p> + +<p>Ngoài <code>false</code> ra, các biểu thức falsy có thể xảy ra bao gồm: <code>null</code>, <code><code>NaN</code></code>, <code><code><code>0</code></code></code>, xâu ký tự rỗng (<code><code><code><code>""</code></code></code></code>), và <code><code><code><code>undefined</code></code></code></code>. Nếu <code>condition</code> là một trong những gì vừa liệt kê phía trên, kết quả của biểu thức điều kiện sẽ là <code>exprF</code>.</p> + +<p>Ví dụ đơn giản:</p> + +<pre class="brush: js">var age = 26; +var beverage = (age >= 21) ? "Beer" : "Juice"; +console.log(beverage); // "Beer" +</pre> + +<p>Thường dùng để xử lý giá trị <code>null</code>:</p> + +<pre class="brush: js">function greeting(person) { + var name = person ? person.name : "stranger"; + return "Howdy, " + name; +} + +console.log(greeting({name: 'Alice'})); // "Howdy, Alice" +console.log(greeting(null)); // "Howdy, stranger" +</pre> + +<h3 id="Điều_kiện_nối_tiếp">Điều kiện nối tiếp</h3> + +<p>Toán tử điều kiện tuân theo suy dẫn phải, tức là nó có thể được gọi "nối tiếp" theo cách sau đây, tương tự như với <code>if … else if … else if … else</code> nối tiếp nhau:</p> + +<pre class="brush: js">function example(…) { + return condition1 ? value1 + : condition2 ? value2 + : condition3 ? value3 + : value4; +} + +// Equivalent to: + +function example(…) { + if (condition1) { return value1; } + else if (condition2) { return value2; } + else if (condition3) { return value3; } + else { return value4; } +} +</pre> + +<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">Bình luận</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-conditional-operator', 'Conditional Operator')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-conditional-operator', 'Conditional Operator')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.12', 'The conditional operator')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES1', '#sec-11.12', 'The conditional operator')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Định nghĩa lần đầu. Cài đặt trong JavaScript 1.0.</td> + </tr> + </tbody> +</table> + +<h2 id="Tương_thích_trình_duyệt">Tương thích trình duyệt</h2> + + + +<p>{{Compat("javascript.operators.conditional")}}</p> + +<h2 id="Xem_thêm">Xem thêm</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else">Lệnh if</a></li> +</ul> diff --git a/files/vi/web/javascript/reference/operators/delete/index.html b/files/vi/web/javascript/reference/operators/delete/index.html new file mode 100644 index 0000000000..46a837d094 --- /dev/null +++ b/files/vi/web/javascript/reference/operators/delete/index.html @@ -0,0 +1,292 @@ +--- +title: delete operator +slug: Web/JavaScript/Reference/Operators/delete +translation_of: Web/JavaScript/Reference/Operators/delete +--- +<div>{{jsSidebar("Operators")}}</div> + +<p><span class="seoSummary"><strong>Toán tử <code>delete</code></strong> của JavaScript loại bỏ một thuộc tính khỏi object; nếu không tồn tại tham chiếu tới thuộc tính, nó sẽ tự động giải phóng.</span></p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-deleteoperator.html")}}</div> + + + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox">delete <em>expression</em> </pre> + +<p>với <em>expression</em> thực thi thành tham chiếu đến <a href="/en-US/docs/Glossary/property/JavaScript">thuộc tính</a> nào đó, tức là:</p> + +<pre class="syntaxbox">delete <em>object.property</em> +delete <em>object</em>['<em>property</em>'] +</pre> + +<h3 id="Tham_số">Tham số</h3> + +<dl> + <dt><code>object</code></dt> + <dd>Tên object, hoặc biểu thức thực thi tới object.</dd> + <dt><code>property</code></dt> + <dd>Thuộc tính muốn xoá.</dd> +</dl> + +<h3 id="Giá_trị_trả_về">Giá trị trả về</h3> + +<p><code>true</code> cho mọi trường hợp trừ khi thuộc tính là <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty">own</a> <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Cant_delete">non-configurable</a>, trong trường hợp đó, trả về <code>false</code> trong chế độ non-strict.</p> + +<h3 id="Ngoại_lệ">Ngoại lệ</h3> + +<p>Quăng {{jsxref("TypeError")}} trong <a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode"> chế độ strict</a> nếu thuộc tính là own non-configurable.</p> + +<h2 id="Mô_tả">Mô tả</h2> + +<p>Khác với suy nghĩ của nhiều người, toán tử <code>delete</code> <strong>không</strong> trực tiếp giải phóng bộ nhớ. Quản lý bộ nhớ được thực hiện trung gian qua việc bẻ tham chiếu. Xem trang <a href="/en-US/docs/Web/JavaScript/Memory_Management">quản lý bộ nhớ</a> để biết thêm chi tiết.</p> + +<p>Toán tử <code><strong>delete</strong></code> loại bỏ thuộc tính xác định trong object. Nếu xoá thành công, nó sẽ trả về <code>true</code>, ngoài ra thì <code>false</code>. Tuy nhiên, hãy lưu ý những kịch bản có thể xảy đến sau đây:</p> + +<ul> + <li>Nếu thuộc tính muốn xoá không tồn tại, <code>delete</code> sẽ không có tác dụng và sẽ trả về <code>true</code></li> + <li>Nếu tồn tại thuộc tính có cùng tên trong prototype nối với object, thì sau khi xoá xong, object sẽ dùng thuộc tính từ prototype đó (nói cách khác, <code>delete</code> chỉ có tác dụng với những thuộc tính của riêng object).</li> + <li>Bất cứ thuộc tính nào được khởi tạo bằng {{jsxref("Statements/var","var")}} không thể bị xoá khỏi phạm vi toàn cục hoặc phạm vi hàm. + <ul> + <li>Vì thế, <code>delete</code> không thể xoá bất cứ hàm nào trong phạm vi toàn cục (cho dù là một phần của định nghĩa hàm hay biểu thức hàm).</li> + <li>Các hàm là một phần của object (tách biệt với phạm vi toàn cục) có thể bị xoá với <code>delete</code>.</li> + </ul> + </li> + <li>Bất cứ thuộc tính nào được khởi tạo bởi {{jsxref("Statements/let","let")}} hoặc {{jsxref("Statements/const","const")}} không thể bị xoá khỏi phạm vi mà chúng được khai báo.</li> + <li>Thuộc tính không-thể-cấu-hình không thể bị loại bỏ. Các thuộc tính này bao gồm các object dựng sẵn như {{jsxref("Math")}}, {{jsxref("Array")}}, {{jsxref("Object")}} và thuộc tính được tạo ra như thuộc tính không-thể-cấu-hình bằng phương thức như là {{jsxref("Object.defineProperty()")}}.</li> +</ul> + +<p>Snippet sau đưa ra ví dụ đơn giản:</p> + +<pre class="brush: js">var Employee = { + age: 28, + name: 'abc', + designation: 'developer' +} + +console.log(delete Employee.name); // trả về true +console.log(delete Employee.age); // trả về true + +// Khi cố xoá một thuộc tính không tồn tại +// sẽ trả về giá trị true +console.log(delete Employee.salary); // trả về true +</pre> + +<h3 id="Thuộc_tính_không-thể-cấu-hình"><strong>Thuộc tính không-thể-cấu-hình</strong></h3> + +<p>Khi một thuộc tính được đánh dấu không-thể-cấu-hình, <code>delete</code> không có tác dụng nào, và sẽ trả về <code>false</code>. Trong chế độ strict, lỗi <code>TypeError</code> sẽ nhảy ra.</p> + +<pre class="brush: js">var Employee = {}; +Object.defineProperty(Employee, 'name', {configurable: false}); + +console.log(delete Employee.name); // trả về false +</pre> + +<p>{{jsxref("Statements/var","var")}}, {{jsxref("Statements/let","let")}} và {{jsxref("Statements/const","const")}} tạo ra thuộc tính không-thể-cấu-hình mà không thể xoá bằng toán tử <code>delete</code>:</p> + +<pre class="brush: js">var nameOther = 'XYZ'; + +// Ta có thể truy cập vào thuộc tính toàn cục này thông qua: +Object.getOwnPropertyDescriptor(window, 'nameOther'); + +// output: Object {value: "XYZ", +// writable: true, +// enumerable: true, +// <strong>configurable: false</strong>} + +// Bởi vì "nameOther" được thêm vào nhờ dùng +// từ khoá var, nên nó được đánh dấu là "không-thể-cấu-hình" + +delete nameOther; // trả về false</pre> + +<p>Trong chế độ strict, ngoại lệ sẽ quăng ra.</p> + +<h3 id="Chế_độ_strict_và_non-strict"><strong>Chế độ strict và non-strict</strong></h3> + +<p>Khi ở trong chế độ strict, nếu <code>delete</code> được dùng để tham chiếu trực tiếp tới một biến, một đối số của hàm hoặc tên hàm, nó sẽ quăng ra {{jsxref("SyntaxError")}}<strong>.</strong></p> + +<p>Bất cứ biến nào được định nghĩa với <code>var</code> đều được đánh dấu là không-thể-cấu-hình. Trong ví dụ sau đây, <code>salary</code> là không-thể-cấu-hình và không thể xoá. Trong chế độ non-strict, phép toán <code>delete</code> sẽ trả về <code>false</code>.</p> + +<pre class="brush: js">function Employee() { + delete salary; + var salary; +} + +Employee(); +</pre> + +<p>Cùng xem mã nguồn tương tự hoạt động ra sao trong chế độ strict nhé. Thay vì trả về <code>false</code>, <code>SyntaxError</code> được quăng ra.</p> + +<pre class="brush: js">"use strict"; + +function Employee() { + delete salary; // SyntaxError + var salary; +} + +// Tương tự, bất cứ truy nhập trực tiếp nào vào hàm +// dùng delete đều quăng ra SyntaxError + +function DemoFunction() { + //vài đoạn code +} + +delete DemoFunction; // SyntaxError +</pre> + +<h2 id="Ví_dụ">Ví dụ</h2> + +<pre class="brush: js">// Tạo thuộc tính adminName trên phạm vi toàn cục. +adminName = 'xyz'; + +// Tạo thuộc tính empCount trên phạm vi toàn cục =. +// Vì dùng var, thuộc tính này được đánh dấu là không-thể-cấu-hình. +// Điều tương tự xảy đến với let và const. +var empCount = 43; + +EmployeeDetails = { + name: 'xyz', + age: 5, + designation: 'Developer' +}; + +// adminName là thuộc tính trên phạm vi toàn cục. +// Nó có thể bị xoá bởi được khởi tạo mà không dùng var, +// và vì thế khả cấu. +delete adminName; // trả về true + +// Ngược lại, empCount không khả cấu +// bởi dùng var. +delete empCount; // trả về false + +// Có thể dùng delete để loại bỏ thuộc tính khỏi object. +delete EmployeeDetails.name; // trả về true + +<strong>// </strong>Thậm chí thuộc tính không tồn tại, delete vẫn trả về "true". +delete EmployeeDetails.salary; // trả về true + +// delete không có tác dụng với thuộc tính dựng sẵn. +delete Math.PI; // trả về false + +// EmployeeDetails là thuộc tính trong phạm vi toàn cục. +// Vì được khởi tạo mà không dùng "var", nó được đánh dấu là khả cấu. +delete EmployeeDetails; // trả về true + +function f() { + var z = 44; + + // delete không có tác dụng với tên biến cục bộ + delete z; // trả về false +} +</pre> + +<h3 id="delete_và_prototype_chain"><code>delete</code> và prototype chain</h3> + +<p>Trong ví dụ sau, ta sẽ xoá một thuộc tính riêng của object mà vẫn tồn tại thuộc tính cùng tên trong prototype chain:</p> + +<pre class="brush: js">function Foo() { + this.bar = 10; +} + +Foo.prototype.bar = 42; + +var foo = new Foo(); + +// foo.bar liên kết với +// thuộc tính riêng. +console.log(foo.bar); // 10 + +// Xoá thuộc tính riêng trên +// foo object. +delete foo.bar; // trả về true + +// foo.bar vẫn sẵn sàng trên +// prototype chain. +console.log(foo.bar); // 42 + +// Xoá thuộc tính trên prototype. +delete Foo.prototype.bar; // trả về true + +// Thuộc tính "bar" không còn có thể +// kể thừa từ Foo bởi nó đã bị xoá +console.log(foo.bar); // undefined</pre> + +<h3 id="Xoá_phần_tử_mảng"><strong>Xoá phần tử mảng</strong></h3> + +<p>Khi bạn xoá phần tử mảng, độ dài mảng không bị ảnh hưởng. Thậm chí khi bạn xoá phần tử cuối của mảng cũng không thay đổi được điều này.</p> + +<p>Khi toán tử <code>delete</code> loại bỏ một phần tử mảng, phần tử đó không còn trong mảng. Trong ví dụ sau, <code>trees[3]</code> bị xoá bởi <code>delete</code>.</p> + +<pre class="brush: js">var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; +delete trees[3]; +if (3 in trees) { + // không thực thi đoạn code này +}</pre> + +<p>Nếu bạn muốn giữ lại phần tử mảng và gán giá trị undefined cho nó, hãy dùng <code>undefined</code> thay vì toán tử <code>delete</code>. Trong ví dụ sau, <code>trees[3]</code> được gán giá trị undefined, nhưng phần tử mảng vẫn tồn tại:</p> + +<pre class="brush: js">var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; +trees[3] = undefined; +if (3 in trees) { + // đoạn code trong này sẽ chạy +}</pre> + +<p>Thay vì thế, nếu muốn loại bỏ phần tử mảng bằng cách thay đổi nội dung của mảng, hãy dùng phương thức <code>{{jsxref("Array.splice", "splice")}}</code>. Trong ví dụ sau, <code>trees[3]</code> bị xoá bỏ hoàn toàn khỏi mảng thông qua <code>{{jsxref("Array.splice", "splice")}}</code>:</p> + +<pre class="brush: js">var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; +trees.splice(3,1); +console.log(trees); // ["redwood", "bay", "cedar", "maple"] +</pre> + +<h2 id="Đặc_Đặc_tả">Đặc Đặc 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('ESDraft', '#sec-delete-operator', 'The delete Operator')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-delete-operator', 'The delete Operator')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.4.1', 'The delete Operator')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES1', '#sec-11.4.1', 'The delete Operator')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Định nghĩa lần đầu. Cài đặt trong JavaScript 1.2.</td> + </tr> + </tbody> +</table> + +<h2 id="Trình_duyệt_hỗ_trợ">Trình duyệt hỗ trợ</h2> + + + +<p>{{Compat("javascript.operators.delete")}}</p> + +<h2 id="Ghi_chú_Cross-browser">Ghi chú Cross-browser</h2> + +<p>Although ECMAScript makes iteration order of objects implementation-dependent, it may appear that all major browsers support an iteration order based on the earliest added property coming first (at least for properties not on the prototype). However, in the case of Internet Explorer, when one uses <code>delete</code> on a property, some confusing behavior results, preventing other browsers from using simple objects like object literals as ordered associative arrays. In Explorer, while the property <em>value</em> is indeed set to undefined, if one later adds back a property with the same name, the property will be iterated in its <em>old</em> position--not at the end of the iteration sequence as one might expect after having deleted the property and then added it back.</p> + +<p>If you want to use an ordered associative array in a cross-browser environment, use a {{jsxref("Map")}} object if available, or simulate this structure with two separate arrays (one for the keys and the other for the values), or build an array of single-property objects, etc.</p> + +<h2 id="Xem_thêm">Xem thêm</h2> + +<ul> + <li><a href="http://perfectionkills.com/understanding-delete/">Phân tích sâu về delete</a></li> + <li>{{jsxref("Reflect.deleteProperty()")}}</li> + <li>{{jsxref("Map.prototype.delete()")}}</li> +</ul> diff --git a/files/vi/web/javascript/reference/operators/function/index.html b/files/vi/web/javascript/reference/operators/function/index.html new file mode 100644 index 0000000000..1e302774be --- /dev/null +++ b/files/vi/web/javascript/reference/operators/function/index.html @@ -0,0 +1,175 @@ +--- +title: function expression +slug: Web/JavaScript/Reference/Operators/function +translation_of: Web/JavaScript/Reference/Operators/function +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>Từ khóa <strong><code>function </code></strong><code>(hàm)</code> có thể dùng để định nghĩa chức năng bên trong một biểu thức.</p> + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox">var myFunction = function [<em>name</em>]([<em>param1</em>[, <em>param2[</em>, ..., <em>paramN</em>]]]) { + <em>statements</em> +};</pre> + +<h3 id="Tham_số">Tham số</h3> + +<dl> + <dt><code>name</code></dt> + <dd>Tên hàm. Có thể bỏ qua, trong trường hợp chức năng đó là <code>vô danh. </code>Nó mô tả chính xác nhiệm vụ mà <strong>hàm </strong>sẽ làm.</dd> + <dt><code>paramN</code></dt> + <dd>Tên các đối số truyền vào.</dd> + <dt><code>statements</code></dt> + <dd>Các câu lệnh xử lý các đối số <strong><code>paramN </code></strong>truyền vào.</dd> +</dl> + +<h2 id="Mô_tả">Mô tả</h2> + +<p>Một biểu thức chức năng (<code>function</code>) is very similar to and has almost the same syntax as a function statement (see <a href="/en-US/docs/Web/JavaScript/Reference/Statements/function">function statement</a> for details). The main difference between a function expression and a function statement is the <em>function name,</em> which can be omitted in function expressions to create <em>anonymous</em> functions. A function expression can be used as a <strong>IIFE </strong>(Immediately Invoked Function Expression) which runs as soon as it is defined. See also the chapter about <a href="/en-US/docs/Web/JavaScript/Reference/Functions">functions</a> for more information.</p> + +<h3 id="Function_expression_hoisting">Function expression hoisting</h3> + +<p>Function expressions in JavaScript are not hoisted, unlike {{jsxref("Statements/function", "function declarations", "#Function_declaration_hoisting")}}. You can't use function expressions before you define them:</p> + +<pre class="brush: js">notHoisted(); // TypeError: notHoisted is not a function + +var notHoisted = function() { + console.log('bar'); +}; +</pre> + +<h2 id="Examples">Examples</h2> + +<p>The following example defines an unnamed function and assigns it to <code>x</code>. The function returns the square of its argument:</p> + +<pre class="brush: js">var x = function(y) { + return y * y; +}; +</pre> + +<h3 id="Named_function_expression">Named function expression</h3> + +<p>If you want to refer to the current function inside the function body, you need to create a named function expression. This name is then local only to the function body (scope). This also avoids using the non-standard <code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee">arguments.callee</a></code> property.</p> + +<pre class="brush: js">var math = { + 'factorial': function factorial(n) { + if (n <= 1) + return 1; + return n * factorial(n - 1); + } +}; +</pre> + +<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('ESDraft', '#sec-function-definitions', 'Function definitions')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-13', 'Function definition')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES3', '#sec-13', 'Function definition')}}</td> + <td>{{Spec2('ES3')}}</td> + <td>Initial definition. Implemented in JavaScript 1.5.</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td>Trailing comma in parameters</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoDesktop("52.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</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>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td>Trailing comma in parameters</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoMobile("52.0")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{jsxref("Functions_and_function_scope", "Functions and function scope")}}</li> + <li>{{jsxref("Function")}}</li> + <li>{{jsxref("Statements/function", "function statement")}}</li> + <li>{{jsxref("Statements/function*", "function* statement")}}</li> + <li>{{jsxref("Operators/function*", "function* expression")}}</li> + <li>{{jsxref("GeneratorFunction")}}</li> +</ul> diff --git a/files/vi/web/javascript/reference/operators/index.html b/files/vi/web/javascript/reference/operators/index.html new file mode 100644 index 0000000000..139208dbca --- /dev/null +++ b/files/vi/web/javascript/reference/operators/index.html @@ -0,0 +1,298 @@ +--- +title: Expressions and operators +slug: Web/JavaScript/Reference/Operators +tags: + - JavaScript + - NeedsTranslation + - Operators + - TopicStub +translation_of: Web/JavaScript/Reference/Operators +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>This chapter documents all the JavaScript language operators, expressions and keywords.</p> + +<h2 id="Expressions_and_operators_by_category">Expressions and operators by category</h2> + +<p>For an alphabetical listing see the sidebar on the left.</p> + +<h3 id="Primary_expressions">Primary expressions</h3> + +<p>Basic keywords and general expressions in JavaScript.</p> + +<dl> + <dt>{{jsxref("Operators/this", "this")}}</dt> + <dd>The <code>this</code> keyword refers to the function's execution context.</dd> + <dt>{{jsxref("Operators/function", "function")}}</dt> + <dd>The <code>function</code> keyword defines a function expression.</dd> + <dt>{{jsxref("Operators/class", "class")}}</dt> + <dd>The <code>class</code> keyword defines a class expression.</dd> + <dt>{{jsxref("Operators/function*", "function*")}}</dt> + <dd>The <code>function*</code> keyword defines a generator function expression.</dd> + <dt>{{jsxref("Operators/yield", "yield")}}</dt> + <dd>Pause and resume a generator function.</dd> + <dt>{{jsxref("Operators/yield*", "yield*")}}</dt> + <dd>Delegate to another generator function or iterable object.</dd> + <dt>{{jsxref("Global_Objects/Array", "[]")}}</dt> + <dd>Array initializer/literal syntax.</dd> + <dt>{{jsxref("Operators/Object_initializer", "{}")}}</dt> + <dd>Object initializer/literal syntax.</dd> + <dt>{{jsxref("Global_Objects/RegExp", "/ab+c/i")}}</dt> + <dd>Regular expression literal syntax.</dd> + <dt>{{jsxref("Operators/Grouping", "( )")}}</dt> + <dd>Grouping operator.</dd> +</dl> + +<h3 id="Left-hand-side_expressions">Left-hand-side expressions</h3> + +<p>Left values are the destination of an assignment.</p> + +<dl> + <dt>{{jsxref("Operators/Property_accessors", "Property accessors", "", 1)}}</dt> + <dd>Member operators provide access to a property or method of an object<br> + (<code>object.property</code> and <code>object["property"]</code>).</dd> + <dt>{{jsxref("Operators/new", "new")}}</dt> + <dd>The <code>new</code> operator creates an instance of a constructor.</dd> + <dt><a href="/en-US/docs/Web/JavaScript/Reference/Operators/new.target">new.target</a></dt> + <dd>In constructors, <code>new.target</code> refers to the constructor that was invoked by {{jsxref("Operators/new", "new")}}.</dd> + <dt>{{jsxref("Operators/super", "super")}}</dt> + <dd>The <code>super</code> keyword calls the parent constructor.</dd> + <dt>{{jsxref("Operators/Spread_operator", "...obj")}}</dt> + <dd>The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected.</dd> +</dl> + +<h3 id="Increment_and_decrement">Increment and decrement</h3> + +<p>Postfix/prefix increment and postfix/prefix decrement operators.</p> + +<dl> + <dt>{{jsxref("Operators/Arithmetic_Operators", "A++", "#Increment")}}</dt> + <dd>Postfix increment operator.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "A--", "#Decrement")}}</dt> + <dd>Postfix decrement operator.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "++A", "#Increment")}}</dt> + <dd>Prefix increment operator.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "--A", "#Decrement")}}</dt> + <dd>Prefix decrement operator.</dd> +</dl> + +<h3 id="Unary_operators">Unary operators</h3> + +<p>A unary operation is operation with only one operand.</p> + +<dl> + <dt>{{jsxref("Operators/delete", "delete")}}</dt> + <dd>The <code>delete</code> operator deletes a property from an object.</dd> + <dt>{{jsxref("Operators/void", "void")}}</dt> + <dd>The <code>void</code> operator discards an expression's return value.</dd> + <dt>{{jsxref("Operators/typeof", "typeof")}}</dt> + <dd>The <code>typeof</code> operator determines the type of a given object.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "+", "#Unary_plus")}}</dt> + <dd>The unary plus operator converts its operand to Number type.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "-", "#Unary_negation")}}</dt> + <dd>The unary negation operator converts its operand to Number type and then negates it.</dd> + <dt>{{jsxref("Operators/Bitwise_Operators", "~", "#Bitwise_NOT")}}</dt> + <dd>Bitwise NOT operator.</dd> + <dt>{{jsxref("Operators/Logical_Operators", "!", "#Logical_NOT")}}</dt> + <dd>Logical NOT operator.</dd> +</dl> + +<h3 id="Arithmetic_operators">Arithmetic operators</h3> + +<p>Arithmetic operators take numerical values (either literals or variables) as their operands and return a single numerical value.</p> + +<dl> + <dt>{{jsxref("Operators/Arithmetic_Operators", "+", "#Addition")}}</dt> + <dd>Addition operator.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "-", "#Subtraction")}}</dt> + <dd>Subtraction operator.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "/", "#Division")}}</dt> + <dd>Division operator.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "*", "#Multiplication")}}</dt> + <dd>Multiplication operator.</dd> + <dt>{{jsxref("Operators/Arithmetic_Operators", "%", "#Remainder")}}</dt> + <dd>Remainder operator.</dd> +</dl> + +<dl> + <dt>{{jsxref("Operators/Arithmetic_Operators", "**", "#Exponentiation")}}</dt> + <dd>Exponentiation operator.</dd> +</dl> + +<h3 id="Relational_operators">Relational operators</h3> + +<p>A comparison operator compares its operands and returns a <code>Boolean</code> value based on whether the comparison is true.</p> + +<dl> + <dt>{{jsxref("Operators/in", "in")}}</dt> + <dd>The <code>in</code> operator determines whether an object has a given property.</dd> + <dt>{{jsxref("Operators/instanceof", "instanceof")}}</dt> + <dd>The <code>instanceof</code> operator determines whether an object is an instance of another object.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", "<", "#Less_than_operator")}}</dt> + <dd>Less than operator.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", ">", "#Greater_than_operator")}}</dt> + <dd>Greater than operator.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", "<=", "#Less_than_or_equal_operator")}}</dt> + <dd>Less than or equal operator.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", ">=", "#Greater_than_or_equal_operator")}}</dt> + <dd>Greater than or equal operator.</dd> +</dl> + +<div class="note"> +<p><strong>Note: =></strong> is not an operator, but the notation for <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">Arrow functions</a>.</p> +</div> + +<h3 id="Equality_operators">Equality operators</h3> + +<p>The result of evaluating an equality operator is always of type <code>Boolean</code> based on whether the comparison is true.</p> + +<dl> + <dt>{{jsxref("Operators/Comparison_Operators", "==", "#Equality")}}</dt> + <dd>Equality operator.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", "!=", "#Inequality")}}</dt> + <dd>Inequality operator.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", "===", "#Identity")}}</dt> + <dd>Identity operator.</dd> + <dt>{{jsxref("Operators/Comparison_Operators", "!==", "#Nonidentity")}}</dt> + <dd>Nonidentity operator.</dd> +</dl> + +<h3 id="Bitwise_shift_operators">Bitwise shift operators</h3> + +<p>Operations to shift all bits of the operand.</p> + +<dl> + <dt>{{jsxref("Operators/Bitwise_Operators", "<<", "#Left_shift")}}</dt> + <dd>Bitwise left shift operator.</dd> + <dt>{{jsxref("Operators/Bitwise_Operators", ">>", "#Right_shift")}}</dt> + <dd>Bitwise right shift operator.</dd> + <dt>{{jsxref("Operators/Bitwise_Operators", ">>>", "#Unsigned_right_shift")}}</dt> + <dd>Bitwise unsigned right shift operator.</dd> +</dl> + +<h3 id="Binary_bitwise_operators">Binary bitwise operators</h3> + +<p>Bitwise operators treat their operands as a set of 32 bits (zeros and ones) and return standard JavaScript numerical values.</p> + +<dl> + <dt>{{jsxref("Operators/Bitwise_Operators", "&", "#Bitwise_AND")}}</dt> + <dd>Bitwise AND.</dd> + <dt>{{jsxref("Operators/Bitwise_Operators", "|", "#Bitwise_OR")}}</dt> + <dd>Bitwise OR.</dd> + <dt>{{jsxref("Operators/Bitwise_Operators", "^", "#Bitwise_XOR")}}</dt> + <dd>Bitwise XOR.</dd> +</dl> + +<h3 id="Binary_logical_operators">Binary logical operators</h3> + +<p>Logical operators are typically used with boolean (logical) values, and when they are, they return a boolean value.</p> + +<dl> + <dt>{{jsxref("Operators/Logical_Operators", "&&", "#Logical_AND")}}</dt> + <dd>Logical AND.</dd> + <dt>{{jsxref("Operators/Logical_Operators", "||", "#Logical_OR")}}</dt> + <dd>Logical OR.</dd> +</dl> + +<h3 id="Conditional_(ternary)_operator">Conditional (ternary) operator</h3> + +<dl> + <dt>{{jsxref("Operators/Conditional_Operator", "(condition ? ifTrue : ifFalse)")}}</dt> + <dd> + <p>The conditional operator returns one of two values based on the logical value of the condition.</p> + </dd> +</dl> + +<h3 id="Assignment_operators">Assignment operators</h3> + +<p>An assignment operator assigns a value to its left operand based on the value of its right operand.</p> + +<dl> + <dt>{{jsxref("Operators/Assignment_Operators", "=", "#Assignment")}}</dt> + <dd>Assignment operator.</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "*=", "#Multiplication_assignment")}}</dt> + <dd>Multiplication assignment.</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "/=", "#Division_assignment")}}</dt> + <dd>Division assignment.</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "%=", "#Remainder_assignment")}}</dt> + <dd>Remainder assignment.</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "+=", "#Addition_assignment")}}</dt> + <dd>Addition assignment.</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "-=", "#Subtraction_assignment")}}</dt> + <dd>Subtraction assignment</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "<<=", "#Left_shift_assignment")}}</dt> + <dd>Left shift assignment.</dd> + <dt>{{jsxref("Operators/Assignment_Operators", ">>=", "#Right_shift_assignment")}}</dt> + <dd>Right shift assignment.</dd> + <dt>{{jsxref("Operators/Assignment_Operators", ">>>=", "#Unsigned_right_shift_assignment")}}</dt> + <dd>Unsigned right shift assignment.</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "&=", "#Bitwise_AND_assignment")}}</dt> + <dd>Bitwise AND assignment.</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "^=", "#Bitwise_XOR_assignment")}}</dt> + <dd>Bitwise XOR assignment.</dd> + <dt>{{jsxref("Operators/Assignment_Operators", "|=", "#Bitwise_OR_assignment")}}</dt> + <dd>Bitwise OR assignment.</dd> + <dt>{{jsxref("Operators/Destructuring_assignment", "[a, b] = [1, 2]")}}<br> + {{jsxref("Operators/Destructuring_assignment", "{a, b} = {a:1, b:2}")}}</dt> + <dd> + <p>Destructuring assignment allows you to assign the properties of an array or object to variables using syntax that looks similar to array or object literals.</p> + </dd> +</dl> + +<h3 id="Comma_operator">Comma operator</h3> + +<dl> + <dt>{{jsxref("Operators/Comma_Operator", ",")}}</dt> + <dd>The comma operator allows multiple expressions to be evaluated in a single statement and returns the result of the last expression.</dd> +</dl> + +<h3 id="Non-standard_features">Non-standard features</h3> + +<dl> + <dt>{{non-standard_inline}} {{jsxref("Operators/Legacy_generator_function", "Legacy generator function", "", 1)}}</dt> + <dd>The <code>function</code> keyword can be used to define a legacy generator function inside an expression. To make the function a legacy generator, the function body should contains at least one {{jsxref("Operators/yield", "yield")}} expression.</dd> + <dt>{{non-standard_inline}} {{jsxref("Operators/Expression_closures", "Expression closures", "", 1)}}</dt> + <dd>The expression closure syntax is a shorthand for writing simple function.</dd> + <dt>{{non-standard_inline}} {{jsxref("Operators/Array_comprehensions", "[for (x of y) x]")}}</dt> + <dd>Array comprehensions.</dd> + <dt>{{non-standard_inline}} {{jsxref("Operators/Generator_comprehensions", "(for (x of y) y)")}}</dt> + <dd>Generator comprehensions.</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-11', 'Expressions')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11', 'Expressions')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-ecmascript-language-expressions', 'ECMAScript Language: Expressions')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>New: Spread operator, destructuring assignment, <code>super</code> keyword.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-ecmascript-language-expressions', 'ECMAScript Language: Expressions')}}</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/Operator_Precedence">Operator precedence</a></li> +</ul> diff --git a/files/vi/web/javascript/reference/operators/operator_precedence/index.html b/files/vi/web/javascript/reference/operators/operator_precedence/index.html new file mode 100644 index 0000000000..efa25029b2 --- /dev/null +++ b/files/vi/web/javascript/reference/operators/operator_precedence/index.html @@ -0,0 +1,477 @@ +--- +title: Operator precedence +slug: Web/JavaScript/Reference/Operators/Operator_Precedence +translation_of: Web/JavaScript/Reference/Operators/Operator_Precedence +--- +<div><font><font>{{jsSidebar ("Toán tử")}}</font></font></div> + +<p><strong><font><font>Mức độ ưu tiên của toán tử</font></font></strong><font><font> xác định cách các toán tử được phân tích cú pháp liên quan đến nhau. </font><font>Các toán tử có mức độ ưu tiên cao hơn trở thành toán hạng của các toán tử có mức độ ưu tiên thấp hơn.</font></font></p> + +<div><font><font>{{EmbedInteractiveExample ("pages / js / expression-operatorprecedence.html")}}</font></font></div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="Precedence_And_Associativity">Precedence And Associativity</h2> + +<p>Consider an expression describable by the representation below. Note that both OP<sub>1</sub> and OP<sub>2</sub> are fill-in-the-blanks for OPerators.</p> + +<pre class="syntaxbox notranslate">a OP<sub>1</sub> b OP<sub>2</sub> c</pre> + +<p>If <code>OP<sub>1</sub></code> and <code>OP<sub>2</sub></code> have different precedence levels (see the table below), the operator with the highest precedence goes first and associativity does not matter. Observe how multiplication has higher precedence than addition and executed first, even though addition is written first in the code.</p> + +<pre class="brush: js notranslate">console.log(3 + 10 * 2); // logs 23 +console.log(3 + (10 * 2)); // logs 23 because parentheses here are superfluous +console.log((3 + 10) * 2); // logs 26 because the parentheses change the order +</pre> + +<p>Left-associativity (left-to-right) means that it is processed as <code>(a OP<sub>1</sub> b) OP<sub>2</sub> c</code>, while right-associativity (right-to-left) means it is interpreted as <code>a OP<sub>1</sub> (b OP<sub>2</sub> c)</code>. Assignment operators are right-associative, so you can write:</p> + +<pre class="brush: js notranslate">a = b = 5; // same as writing a = (b = 5); +</pre> + +<p>with the expected result that <code>a</code> and <code>b</code> get the value 5. This is because the assignment operator returns the value that is assigned. First, <code>b</code> is set to 5. Then the <code>a</code> is also set to 5, the return value of <code>b = 5</code>, aka right operand of the assignment.</p> + +<p>As another example, the unique exponentiation operator has right-associativity, whereas other arithmetic operators have left-associativity. It is interesting to note that, the order of evaluation is always left-to-right irregardless of associativity.</p> + +<table class="standard-table"> + <tbody> + <tr> + <td>Code</td> + <td>Output</td> + </tr> + <tr> + <td> + <pre class="brush: js notranslate"> +function echo(name, num) { + console.log("Evaluating the " + name + " side"); + return num; +} +// Notice the division operator (/) +console.log(echo("left", 6) / echo("right", 2)); +</pre> + </td> + <td> + <pre class="notranslate"> +Evaluating the left side +Evaluating the right side +3 +</pre> + </td> + </tr> + <tr> + <td> + <pre class="brush: js notranslate"> +function echo(name, num) { + console.log("Evaluating the " + name + " side"); + return num; +} +// Notice the exponentiation operator (**) +console.log(echo("left", 2) ** echo("right", 3));</pre> + </td> + <td> + <pre class="notranslate"> +Evaluating the left side +Evaluating the right side +8</pre> + </td> + </tr> + </tbody> +</table> + +<p>The difference in associativity comes into play when there are multiple operators of the same precedence. With only one operator or operators of different precedences, associativity doesn't affect the output, as seen in the example above. In the example below, observe how associativity affects the output when multiple of the same operator are used.</p> + +<table class="standard-table"> + <tbody> + <tr> + <td>Code</td> + <td>Output</td> + </tr> + <tr> + <td> + <pre class="brush: js notranslate"> +function echo(name, num) { + console.log("Evaluating the " + name + " side"); + return num; +} +// Notice the division operator (/) +console.log(echo("left", 6) / echo("middle", 2) / echo("right", 3)); +</pre> + </td> + <td> + <pre class="notranslate"> +Evaluating the left side +Evaluating the middle side +Evaluating the right side +1 +</pre> + </td> + </tr> + <tr> + <td> + <pre class="brush: js notranslate"> +function echo(name, num) { + console.log("Evaluating the " + name + " side"); + return num; +} +// Notice the exponentiation operator (**) +console.log(echo("left", 2) ** echo("middle", 3) ** echo("right", 2)); +</pre> + </td> + <td> + <pre class="notranslate"> +Evaluating the left side +Evaluating the middle side +Evaluating the right side +512 +</pre> + </td> + </tr> + <tr> + <td> + <pre class="brush: js notranslate"> +function echo(name, num) { + console.log("Evaluating the " + name + " side"); + return num; +} +// Notice the parentheses around the left and middle exponentiation +console.log((echo("left", 2) ** echo("middle", 3)) ** echo("right", 2));</pre> + </td> + <td> + <pre class="notranslate"> +Evaluating the left side +Evaluating the middle side +Evaluating the right side +64</pre> + </td> + </tr> + </tbody> +</table> + +<p>Looking at the code snippets above, <code>6 / 3 / 2</code> is the same as <code>(6 / 3) / 2</code> because division is left-associative. Exponentiation, on the other hand, is right-associative, so <code>2 ** 3 ** 2</code> is the same as <code>2 ** (3 ** 2)</code>. Thus, doing <code>(2 ** 3) ** 2</code> changes the order and results in the 64 seen in the table above.</p> + +<p>Remember that precedence comes before associativity. So, mixing division and exponentiation, the exponentiation comes before the division. For example, <code>2 ** 3 / 3 ** 2</code> results in 0.8888888888888888 because it is the same as <code>(2 ** 3) / (3 ** 2)</code>.</p> + +<h3 id="Note_on_grouping_and_short-circuiting">Note on grouping and short-circuiting</h3> + +<p>In the table below, <strong>Grouping</strong> is listed as having the highest precedence. However, that does not always mean the expression within the grouping symbols <code>( … )</code> is evaluated first, especially when it comes to short-circuiting.</p> + +<p>Short-circuiting is jargon for conditional evaluation. For example, in the expression <code>a && (b + c)</code>, if <code>a</code> is {{Glossary("falsy")}}, then the sub-expression <code>(b + c)</code> will not even get evaluated, even if it is in parentheses. We could say that the logical disjunction operator ("OR") is "short-circuited". Along with logical disjunction, other short-circuited operators include logical conjunction ("AND"), nullish-coalescing, optional chaining, and the conditional operator. Some more examples follow.</p> + +<pre class="brush: js notranslate">a || (b * c); // evaluate `a` first, then produce `a` if `a` is "truthy" +a && (b < c); // evaluate `a` first, then produce `a` if `a` is "falsy" +a ?? (b || c); // evaluate `a` first, then produce `a` if `a` is not `null` and not `undefined` +a?.b.c; // evaluate `a` first, then produce `undefined` if `a` is `null` or `undefined` +</pre> + +<h2 id="Examples">Examples</h2> + +<pre class="brush: js notranslate">3 > 2 && 2 > 1 +// returns true + +3 > 2 > 1 +// Returns false because 3 > 2 is true, then true is converted to 1 +// in inequality operators, therefore true > 1 becomes 1 > 1, which +// is false. Adding parentheses makes things clear: (3 > 2) > 1. +</pre> + +<h2 id="Table">Table</h2> + +<p>The following table is ordered from highest (21) to lowest (1) precedence.</p> + +<table class="fullwidth-table"> + <tbody> + <tr> + <th>Precedence</th> + <th>Operator type</th> + <th>Associativity</th> + <th>Individual operators</th> + </tr> + <tr> + <td>21</td> + <td>{{jsxref("Operators/Grouping", "Grouping", "", 1)}}</td> + <td>n/a</td> + <td><code>( … )</code></td> + </tr> + <tr> + <td colspan="1" rowspan="5">20</td> + <td>{{jsxref("Operators/Property_Accessors", "Member Access", "#Dot_notation", 1)}}</td> + <td>left-to-right</td> + <td><code>… . …</code></td> + </tr> + <tr> + <td>{{jsxref("Operators/Property_Accessors", "Computed Member Access","#Bracket_notation", 1)}}</td> + <td>left-to-right</td> + <td><code>… [ … ]</code></td> + </tr> + <tr> + <td>{{jsxref("Operators/new","new")}} (with argument list)</td> + <td>n/a</td> + <td><code>new … ( … )</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Guide/Functions">Function Call</a></td> + <td>left-to-right</td> + <td><code>… ( <var>… </var>)</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining">Optional chaining</a></td> + <td>left-to-right</td> + <td><code>?.</code></td> + </tr> + <tr> + <td rowspan="1">19</td> + <td>{{jsxref("Operators/new","new")}} (without argument list)</td> + <td>right-to-left</td> + <td><code>new …</code></td> + </tr> + <tr> + <td rowspan="2">18</td> + <td>{{jsxref("Operators/Arithmetic_Operators","Postfix Increment","#Increment", 1)}}</td> + <td colspan="1" rowspan="2">n/a</td> + <td><code>… ++</code></td> + </tr> + <tr> + <td>{{jsxref("Operators/Arithmetic_Operators","Postfix Decrement","#Decrement", 1)}}</td> + <td><code>… --</code></td> + </tr> + <tr> + <td colspan="1" rowspan="10">17</td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_NOT">Logical NOT</a></td> + <td colspan="1" rowspan="10">right-to-left</td> + <td><code>! …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT">Bitwise NOT</a></td> + <td><code>~ …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus">Unary Plus</a></td> + <td><code>+ …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_negation">Unary Negation</a></td> + <td><code>- …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Increment">Prefix Increment</a></td> + <td><code>++ …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Decrement">Prefix Decrement</a></td> + <td><code>-- …</code></td> + </tr> + <tr> + <td>{{jsxref("Operators/typeof", "typeof")}}</td> + <td><code>typeof …</code></td> + </tr> + <tr> + <td>{{jsxref("Operators/void", "void")}}</td> + <td><code>void …</code></td> + </tr> + <tr> + <td><font><font>{{jsxref ("Toán tử / xóa", "xóa")}}</font></font></td> + <td><code>delete …</code></td> + </tr> + <tr> + <td><font><font>{{jsxref ("Toán tử / await", "await")}}</font></font></td> + <td><code>await …</code></td> + </tr> + <tr> + <td><font><font>16</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Exponentiation"><font><font>Luỹ thừa</font></font></a></td> + <td><font><font>phải sang trái</font></font></td> + <td><code>… ** …</code></td> + </tr> + <tr> + <td rowspan="3"><font><font>15</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Multiplication"><font><font>Phép nhân</font></font></a></td> + <td colspan="1" rowspan="3"><font><font>trái sang phải</font></font></td> + <td><code>… * …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Division"><font><font>Sư đoàn</font></font></a></td> + <td><code>… / …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Remainder"><font><font>Phần còn lại</font></font></a></td> + <td><code>… % …</code></td> + </tr> + <tr> + <td rowspan="2"><font><font>14</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Addition"><font><font>Thêm vào</font></font></a></td> + <td colspan="1" rowspan="2"><font><font>trái sang phải</font></font></td> + <td><code>… + …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Subtraction"><font><font>Phép trừ</font></font></a></td> + <td><code>… - …</code></td> + </tr> + <tr> + <td rowspan="3"><font><font>13</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators"><font><font>Dịch chuyển sang trái theo chiều bit</font></font></a></td> + <td colspan="1" rowspan="3"><font><font>trái sang phải</font></font></td> + <td><code>… << …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators"><font><font>Chuyển sang phải theo chiều bit</font></font></a></td> + <td><code>… >> …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators"><font><font>Chuyển sang phải không dấu bit</font></font></a></td> + <td><code>… >>> …</code></td> + </tr> + <tr> + <td rowspan="6"><font><font>12</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Less_than_operator"><font><font>Ít hơn</font></font></a></td> + <td colspan="1" rowspan="6"><font><font>trái sang phải</font></font></td> + <td><code>… < …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Less_than__or_equal_operator"><font><font>Nhỏ hơn hoặc bằng</font></font></a></td> + <td><code>… <= …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Greater_than_operator"><font><font>Lớn hơn</font></font></a></td> + <td><code>… > …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Greater_than_or_equal_operator"><font><font>Lớn hơn hoặc bằng</font></font></a></td> + <td><code>… >= …</code></td> + </tr> + <tr> + <td><font><font>{{jsxref ("Toán tử / trong", "trong")}}</font></font></td> + <td><code>… in …</code></td> + </tr> + <tr> + <td><font><font>{{jsxref ("Toán tử / instanceof", "instanceof")}}</font></font></td> + <td><code>… instanceof …</code></td> + </tr> + <tr> + <td rowspan="4"><font><font>11</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality"><font><font>Bình đẳng</font></font></a></td> + <td colspan="1" rowspan="4"><font><font>trái sang phải</font></font></td> + <td><code>… == …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Inequality"><font><font>Bất bình đẳng</font></font></a></td> + <td><code>… != …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity"><font><font>Bình đẳng nghiêm ngặt</font></font></a></td> + <td><code>… === …</code></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Nonidentity"><font><font>Bất bình đẳng nghiêm ngặt</font></font></a></td> + <td><code>… !== …</code></td> + </tr> + <tr> + <td><font><font>10</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_AND"><font><font>Bitwise VÀ</font></font></a></td> + <td><font><font>trái sang phải</font></font></td> + <td><code>… & …</code></td> + </tr> + <tr> + <td><font><font>9</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_XOR"><font><font>Bitwise XOR</font></font></a></td> + <td><font><font>trái sang phải</font></font></td> + <td><code>… ^ …</code></td> + </tr> + <tr> + <td><font><font>số 8</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_OR"><font><font>Bitwise HOẶC</font></font></a></td> + <td><font><font>trái sang phải</font></font></td> + <td><code>… | …</code></td> + </tr> + <tr> + <td><font><font>7</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_AND"><font><font>Logic AND</font></font></a></td> + <td><font><font>trái sang phải</font></font></td> + <td><code>… && …</code></td> + </tr> + <tr> + <td><font><font>6</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_OR"><font><font>Logic HOẶC</font></font></a></td> + <td><font><font>trái sang phải</font></font></td> + <td><code>… || …</code></td> + </tr> + <tr> + <td><font><font>5</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator"><font><font>Nhà điều hành liên kết Nullish</font></font></a></td> + <td><font><font>trái sang phải</font></font></td> + <td><code>… ?? …</code></td> + </tr> + <tr> + <td><font><font>4</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator"><font><font>Có điều kiện</font></font></a></td> + <td><font><font>phải sang trái</font></font></td> + <td><code>… ? … : …</code></td> + </tr> + <tr> + <td rowspan="16"><font><font>3</font></font></td> + <td rowspan="16"><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators"><font><font>Chuyển nhượng</font></font></a></td> + <td rowspan="16"><font><font>phải sang trái</font></font></td> + <td><code>… = …</code></td> + </tr> + <tr> + <td><code>… += …</code></td> + </tr> + <tr> + <td><code>… -= …</code></td> + </tr> + <tr> + <td><code>… **= …</code></td> + </tr> + <tr> + <td><code>… *= …</code></td> + </tr> + <tr> + <td><code>… /= …</code></td> + </tr> + <tr> + <td><code>… %= …</code></td> + </tr> + <tr> + <td><code>… <<= …</code></td> + </tr> + <tr> + <td><code>… >>= …</code></td> + </tr> + <tr> + <td><code>… >>>= …</code></td> + </tr> + <tr> + <td><code>… &= …</code></td> + </tr> + <tr> + <td><code>… ^= …</code></td> + </tr> + <tr> + <td><code>… |= …</code></td> + </tr> + <tr> + <td><code>… &&= …</code></td> + </tr> + <tr> + <td><code>… ||= …</code></td> + </tr> + <tr> + <td><code>… ??= …</code></td> + </tr> + <tr> + <td rowspan="2"><font><font>2</font></font></td> + <td><font><font>{{jsxref ("Toán tử / lợi nhuận", "lợi nhuận")}}</font></font></td> + <td colspan="1" rowspan="2"><font><font>phải sang trái</font></font></td> + <td><code>yield …</code></td> + </tr> + <tr> + <td><font><font>{{jsxref ("Toán tử / lợi nhuận *", "lợi nhuận *")}}</font></font></td> + <td><code>yield* …</code></td> + </tr> + <tr> + <td><font><font>1</font></font></td> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator"><font><font>Dấu phẩy / Chuỗi</font></font></a></td> + <td><font><font>trái sang phải</font></font></td> + <td><code>… , …</code></td> + </tr> + </tbody> +</table> diff --git a/files/vi/web/javascript/reference/operators/super/index.html b/files/vi/web/javascript/reference/operators/super/index.html new file mode 100644 index 0000000000..4e5a092475 --- /dev/null +++ b/files/vi/web/javascript/reference/operators/super/index.html @@ -0,0 +1,226 @@ +--- +title: super +slug: Web/JavaScript/Reference/Operators/super +translation_of: Web/JavaScript/Reference/Operators/super +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>Từ khóa <strong>super </strong>được sử dụng để gọi các hàm trên đối tượng cha.</p> + +<p>Các biểu thức super.prop và super[expr] là hợp lệ trong mọi <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions">định nghĩa phương thức</a> ở cả <a href="/en-US/docs/Web/JavaScript/Reference/Classes">classes</a> và <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer">object literals</a>.</p> + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox">super([arguments]); // gọi hàm khởi tạo cha. +super.functionOnParent([arguments]); +</pre> + +<h2 id="Mô_tả">Mô tả</h2> + +<p>Khi được sử dụng trong một hàm khởi tạo, từ khóa super xuất hiện một mình và phải được sử dụng trước khi từ khóa this có thể sử dụng. Từ khóa này cũng có thể được sử dụng để gọi các hàm trên đối tượng cha.</p> + +<h2 id="Ví_dụ">Ví dụ</h2> + +<h3 id="Sử_dụng_super_trong_classes">Sử dụng super trong classes</h3> + +<p>Đoạn code này lấy từ <a href="https://github.com/GoogleChrome/samples/blob/gh-pages/classes-es6/index.html">ví dụ về class</a> (<a href="https://googlechrome.github.io/samples/classes-es6/index.html">live demo</a>). <code>super()</code> ở đây được gọi để tránh việc lặp lại các phần giống nhau của <code>Rectangle</code> và <code>Square</code>.</p> + +<pre class="brush: js">class Polygon { + constructor(height, width) { + this.name = 'Polygon'; + this.height = height; + this.width = width; + } + sayName() { + console.log('Hi, I am a ', this.name + '.'); + } +} + +class Square extends Polygon { + constructor(length) { + this.height; // ReferenceError, super needs to be called first! + + // Here, it calls the parent class' constructor with lengths + // provided for the Polygon's width and height + super(length, length); + + // Note: In derived classes, super() must be called before you + // can use 'this'. Leaving this out will cause a reference error. + this.name = 'Square'; + } + + get area() { + return this.height * this.width; + } + + set area(value) { + this.area = value; + } +}</pre> + +<h3 id="Gọi_super_trên_các_phương_thức_tĩnh">Gọi super trên các phương thức tĩnh</h3> + +<p>Bạn cũng có thể gọi <code>super()</code> trên các phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static">tĩnh</a>.</p> + +<pre class="brush: js">class Human { + constructor() {} + static ping() { + return 'ping'; + } +} + +class Computer extends Human { + constructor() {} + static pingpong() { + return super.ping() + ' pong'; + } +} +Computer.pingpong(); // 'ping pong' +</pre> + +<h3 id="Xóa_các_thuộc_tính_của_super_sẽ_gây_ra_lỗi">Xóa các thuộc tính của super sẽ gây ra lỗi</h3> + +<p>Bạn không thể sử dụng <a href="/en-US/docs/Web/JavaScript/Reference/Operators/delete">thao tác delete</a> và <code>super.prop</code> hoặc <code>super[expr]</code> để xóa một thuộc tính của lớp cha, nó sẽ ném lỗi {{jsxref("ReferenceError")}}.</p> + +<pre class="brush: js">class Base { + constructor() {} + foo() {} +} +class Derived extends Base { + constructor() {} + delete() { + delete super.foo; + } +} + +new Derived().delete(); // ReferenceError: invalid delete involving 'super'. </pre> + +<h3 id="Super.prop_không_thể_ghi_đè_các_thuộc_tính_non-writable">Super.prop không thể ghi đè các thuộc tính non-writable</h3> + +<p>Khi định nghĩa các thuộc tính non-writable ví dụ {{jsxref("Object.defineProperty")}}, <code>super</code> không thể ghi đè giá trị của thuộc tính này.</p> + +<pre class="brush: js">class X { + constructor() { + Object.defineProperty(this, "prop", { + configurable: true, + writable: false, + value: 1 + }); + } + f() { + super.prop = 2; + } +} + +var x = new X(); +x.f(); +console.log(x.prop); // 1 +</pre> + +<h3 id="Sử_dụng_super.prop_trong_object_literals">Sử dụng super.prop trong object literals</h3> + +<p>Super cũng có thể được sử dụng trong <a href="/en-US/docs/">khởi tạo đối tượng hoặc literal</a>. Trong ví dụ này, 2 đối tượng định nghĩa một phương thức. Trong đối tượng thứ hai, <code>super</code> gọi phương thức của đối tượng thứ nhất. Điều này làm được với sự trợ giúp của {{jsxref("Object.setPrototypeOf()")}} cái giúp chúng ta có thể thiết lập prototype của <code>obj2</code> thành <code>obj1</code>, vì thế <code>super</code> có thể tìm <code>method1</code> trên <code>obj1</code>.</p> + +<pre class="brush: js">var obj1 = { + method1() { + console.log("method 1"); + } +} + +var obj2 = { + method2() { + super.method1(); + } +} + +Object.setPrototypeOf(obj2, obj1); +obj2.method2(); // logs "method 1" +</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('ES6', '#sec-super-keyword', 'super')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-super-keyword', 'super')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Khả_năng_tương_thích_của_các_trình_duyệt">Khả năng tương thích của các 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>{{CompatChrome(42.0)}}</td> + <td>{{CompatGeckoDesktop(45)}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</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>Android Webview</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + <th>Chrome for Android</th> + </tr> + <tr> + <td>Hỗ trợ cơ bản</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatChrome(42.0)}}</td> + <td>{{CompatGeckoMobile(45)}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatChrome(42.0)}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="Lưu_ý_cho_Gecko">Lưu ý cho Gecko</h2> + +<ul> + <li>super() chưa làm việc như mong đợi cho việc xây dựng trong các nguyên mẫu</li> +</ul> + +<h2 id="Xem_thêm">Xem thêm</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Classes">Classes</a></li> +</ul> diff --git a/files/vi/web/javascript/reference/operators/this/index.html b/files/vi/web/javascript/reference/operators/this/index.html new file mode 100644 index 0000000000..d3112507cb --- /dev/null +++ b/files/vi/web/javascript/reference/operators/this/index.html @@ -0,0 +1,382 @@ +--- +title: this +slug: Web/JavaScript/Reference/Operators/this +translation_of: Web/JavaScript/Reference/Operators/this +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>Từ khoá<strong> <code>this</code> </strong>của hàm trong JavaScript hơi khác so với các ngôn ngữ khác. Nó cũng có một vài điểm khác nhau giữa 2 chế độ <a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode">strict mode</a> và non-strict mode.</p> + +<p>Trong hầu hết các trường hợp, giá trị của <code>this</code> được xác định bởi cách gọi hàm (runtime binding). Nó không thể được thiết lập bằng cách gán trong khi thực thi, và nó có thể khác nhau mỗi lần hàm được gọi. ES5 giới thiệu phương thức {{jsxref("Function.prototype.bind()", "bind()")}} để <a href="#">thiết lập giá trị của <code>this</code> bất kể hàm được gọi thế nào</a>, và ES2015 giới thiệu <a href="../Functions/Arrow_functions">arrow functions</a> mà không cung cấp ràng buộc với <code>this</code> của chúng (Nó sẽ giữ giá trị <code>this</code> của lexical context kèm theo).</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-this.html")}}</div> + + + +<h2 id="Cú_pháp">Cú pháp</h2> + +<pre class="syntaxbox">this</pre> + +<h3 id="Giá_trị">Giá trị</h3> + +<p>Một thuộc tính của bối cảnh thực thi (global, function or eval), trong non–strict mode, luôn luôn tham chiếu tới một đối tượng và trong strict mode có thể là bất kỳ giá trị nào.</p> + +<h2 id="Global_context">Global context</h2> + +<p>Trong global context (bên ngoài các hàm), <code>this</code> tham chiếu tới global object cho dù trong strict mode hoặc không.</p> + +<pre class="brush:js">// Trong trình duyệt, đối tượng window ?là global object: +console.log(this === window); // true + +a = 37; +console.log(window.a); // 37 + +this.b = "MDN"; +console.log(window.b) // "MDN" +console.log(b) // "MDN" +</pre> + +<div class="blockIndicator note"> +<p><strong>Note:</strong> Bạn có thể dễ dàng lấy được global object bằng cách sử dụng thuộc tính toàn cầu {{jsxref("globalThis")}}, bất kể bối cảnh hiện tại mà mã của bạn đang chạy.</p> +</div> + +<h2 id="Function_context">Function context</h2> + +<p>Bên trong một hàm, giá trị của <code>this</code> phụ thuộc vào cách gọi hàm.</p> + +<h3 id="Simple_call">Simple call</h3> + +<p>Vì đoạn mã sau không ở chế độ <a href="/en-US/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a>, và vì giá trị của <code>this</code> không được thiết lập khi gọi, <code>this</code> mặc định là global objecct, đó là <a href="/en-US/docs/Web/API/Window" title="The Window interface represents a window containing a DOM document; the document property points to the DOM document loaded in that window."><code>window</code></a> trong trình duyệt. </p> + +<pre class="brush:js">function f1() { + return this; +} + +// In a browser: +f1() === window; // true + +// In Node: +f1() === global; // true</pre> + +<p>Tuy nhiên, trong chế độ strict mode, nếu giá trị của <code>this</code> không được thiết lập khi vào bối cảnh thực thi, nó sẽ giữ giá trị <code>undefined</code>, như ví dụ sau<strong>:</strong></p> + +<pre class="brush:js">function f2() { + 'use strict'; // see strict mode + return this; +} + +f2() === undefined; // true +</pre> + +<div class="note"> Trong ví dụ thứ 2, <code>this</code> nên là {{jsxref("undefined")}}, bởi vì <code>f2</code> được gọi 1 cách trực tiếp và không phải là một phương thức hoặc thuộc tính của một đối tượng(ví dụ <code>window.f2()</code>). ?Tính năng này sẽ không được triển khai trong một số trình duyệt khi chúng lần đầu hỗ trợ chế độ <a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode" title="Strict mode">strict mode</a>. Như kết quả trên, chúng không trả về đối tượng <code>window</code>.</div> + +<p>Để thiết lập giá trị cụ thể của <code>this</code> khi gọi hàm, sử dụng {{jsxref("Function.prototype.call()", "call()")}}, hoặc {{jsxref("Function.prototype.apply()", "apply()")}} như các ví dụ dưới đây<strong>.</strong></p> + +<p><strong>Example 1</strong></p> + +<pre class="brush:js" dir="rtl">// Một đối tượng có thể truyền vào như là tham số đầu tiên của call hoặc apply và this sẽ được ràng buộc với nó.. +var obj = {a: 'Custom'}; + +// Thuộc tính này được thiết lập trên global object +var a = 'Global'; + +function whatsThis() { + return this.a; // Giá trị của this phụ thuộc vào cách hàm được gọi. +} + +whatsThis(); // 'Global' +whatsThis.call(obj); // 'Custom' +whatsThis.apply(obj); // 'Custom' +</pre> + +<p><strong>Example 2</strong></p> + +<pre class="brush:js">function add(c, d) { + return this.a + this.b + c + d; +} + +var o = {a: 1, b: 3}; + +// Tham số đầu tiên là đối tượng sử dụng như là +// 'this', tham số tiếp theo được truyền vào là +// đối số trong hàm gọi +add.call(o, 5, 7); // 16 + +// Tham số đầu tiên là đối tượng sử dụng như là +// 'this', tham số thứ 2 là 1 mảng +// các phần tử được sử dụng làm đối số trong lệnh gọi hàm +add.apply(o, [10, 20]); // 34 +</pre> + +<p> Chú ý trong chế độ non–strict mode, với <code>call</code> và <code>apply</code>, nếu giá trị được truyền vào <code>this</code> không phải là đối tượng, một nỗ lực sẽ được thực hiện để chuyển đổi nó thành đối tượng bằng cách sử dụng <code>ToObject</code>. Vì thế nếu bạn truyền vào giá trị primitive như <code>7</code> hoặc <code>'foo'</code>, nó sẽ được chuyển đổi thành Object bằng cách sử dụng các constructor liên quan, do đó <code>7</code> sẽ được chuyển đổi thành đối tượng như tạo bằng <code>new Number(7)</code> và string <code>'foo'</code> cũng được chuyển đổi thành đối tượng như tạo bằng <code>new String('foo')</code>, ví dụ:</p> + +<pre class="brush:js">function bar() { + console.log(Object.prototype.toString.call(this)); +} + +bar.call(7); // [object Number] +bar.call('foo'); // [object String] +</pre> + +<h3 id="The_bind_method">The <code>bind</code> method</h3> + +<p>ECMAScript 5 giới thiệu {{jsxref("Function.prototype.bind()")}}. Gọi <code>f.bind(someObject)</code> tạo ra một hàm mới với cùng thân hàm và phạm vi như hàm <code>f</code>, nhưng <code>this</code> chỉ xảy ra trong hàm ban đầu, trong những hàm mới nó bị ràng buộc vĩnh viễn với đối số đầu tiên của <code>bind</code>, bất kể các hàm được sử dụng thế nào..</p> + +<pre class="brush:js">function f() { + return this.a; +} + +var g = f.bind({a: 'azerty'}); +console.log(g()); // azerty + +var h = g.bind({a: 'yoo'}); // bind only works once! +console.log(h()); // azerty + +var o = {a: 37, f: f, g: g, h: h}; +console.log(o.a, o.f(), o.g(), o.h()); // 37,37, azerty, azerty +</pre> + +<h3 id="Arrow_functions">Arrow functions</h3> + +<p>Trong <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">arrow functions</a>, <code>this</code> giữ giá trị ?<code>this</code> của lexical context kèm theo. Trong đoạn mã toàn cục, nó sẽ được thiết lập là global object.</p> + +<pre class="brush: js">var globalObject = this; +var foo = (() => this); +console.log(foo() === globalObject); // true</pre> + +<div class="note"> +<p> Lưu ý: nếu đối số this được truyền vào call, bind, hoặc apply ?trong việc gọi một arrow function nó sẽ bị bỏ qua. Bạn vẫn có thể thêm các đối số cho việc gọi hàm nhưng đối số đầu tiên (thisArg) nên được đặt thành null.</p> +</div> + +<pre class="brush: js">// Call as a method of an object +var obj = {func: foo}; +console.log(obj.func() === globalObject); // true + +// Attempt to set this using call +console.log(foo.call(obj) === globalObject); // true + +// Attempt to set this using bind +foo = foo.bind(obj); +console.log(foo() === globalObject); // true</pre> + +<p>Không có vấn đề gì ở đây, <code>this</code> của <code>foo</code> vẫn giữ nguyên giá trị khi nó được tạo (trong ví dụ trên, nó là global object). Điều tương tự cũng được áp dụng cho những arrow function được tạo bên trong hàm khác: <code>this</code> của chúng giữ giá trị <code>this</code> của lexical context kèm theo.</p> + +<pre class="brush: js">// Tạo 1 đối tượng với phương thức bar trả về 1 hàm, hàm này sẽ +// trả về this của nó. Hàm trả về là arrow function, +// vì thế this của nó được ràng buộc vĩnh viễn với this của hàm kèm theo. +// Giá trị của bar có thể được thiết lập trong khi gọi hàm, +// lần lượt đặt giá của hàm trả về. +var obj = { + bar: function() { + var x = (() => this); + return x; + } +}; + +// Gọi phương thức bar của obj, thiết lập this là obj. +// Gán một tham chiếu tới hàm trả về là fn +var fn = obj.bar(); + +// Gọi hàm fn mà không thiết lập 'this', +// thông thường sẽ mặc định cho global object hoặc undefined trong strict mode +console.log(fn() === obj); // true + +// Nhưng hãy cẩn thận nếu bạn tham chiếu phương thức của đối tượng mà không gọi nó +var fn2 = obj.bar; +// Gọi hàm arrow function bên trong phương thức bar() +// nó sẽ trả về window, bởi vì nó theo 'this' từ fn2. +console.log(fn2()() == window); // true +</pre> + +<p>Trong ví dụ trên, hàm (gọi nó là hàm ẩn danh A) gán cho <code>obj.bar</code> trả về một hàm khác (gọi là hàm ẩn danh B) mà nó là một arrow function. Kết quả là, <code>this</code> của hàm B được thiết lập vĩnh viễn là <code>this</code> của <code>obj.bar</code> (hàm A) khi được gọi. Khi hàm trả về (hàm B) được gọi, <code>this</code> của nó sẽ luôn là những gì được thiết lập ban đầu. Trong đoạn mã trên, <code>this</code> của hàm B được thiết lập theo <code>this</code> của hàm A đó là <code>obj</code>, vì thế nó vẫn được thiết lập là <code>obj</code> ngay cả khi được gọi theo cách thông thường thiết lập <code>this</code> thành <code>undefined</code> hoặc global object (hoặc bất kỳ phương thức nào khác như trong ví dụ trên được thực thi trong bối cảnh toàn cầu).</p> + +<h3 id="As_an_object_method">As an object method</h3> + +<p>Khi một hàm được gọi như là một phương thức của đối tượng,<code>this</code> được đặt thành đối tượng mà có phương thức được gọi trên.</p> + +<p>Trong ví dụ dưới đây, khi <code>o.f()</code> được gọi, <code>this</code> bên trong hàm sẽ liên kết với đối tượng <code>o</code>.</p> + +<pre class="brush:js">var o = { + prop: 37, + f: function() { + return this.prop; + } +}; + +console.log(o.f()); // 37 +</pre> + +<p>Lưu ý hành vi này hoàn toàn không bị ảnh hưởng bởi cách thức hoặc nơi chức năng được khai báo. Trong ví dụ ở trên, chúng ta khai báo hàm <code>f</code> bên trong đối tượng <code>o</code>. Tuy nhiên, chúng ta có thể dễ dàng khai báo hàm trước và đính kèm nó vào <code>o.f</code>. Làm như vậy sẽ có kết quả tương tự:</p> + +<pre class="brush:js">var o = {prop: 37}; + +function independent() { + return this.prop; +} + +o.f = independent; + +console.log(o.f()); // 37 +</pre> + +<p>Điều này chứng tỏ rằng vấn đề chỉ là việc gọi hàm <code>f</code> của <code>o</code>.</p> + +<p>Tương tự, ràng buộc với <code>this</code> chỉ bị ảnh hưởng bởi tham chiếu trực tiếp nhất. Trong ví dụ dưới, khi chúng ta gọi hàm, chúng ta gọi nó như là một phương thức <code>g</code> của đối tượng <code>o.b</code>. Khi thực thi, <code>this</code> bên trong hàm sẽ tham chiếu tới <code>o.b</code>. Thực tế đối tượng này là một thành viên của <code>o</code> không ảnh hưởng; tham chiếu trực tiếp nhất mới là quan trọng nhất.</p> + +<pre class="brush:js">var o = {prop: 37}; +function independent() { return this.prop; } +o.f = independent; +console.log(o.f()); // 37 bởi vì tham chiếu trực tiếp nhất là o +o.b = {g: independent, prop: 42}; +console.log(o.b.g()); // 42 bởi vì tham chiếu trực tiếp nhất là o.b +</pre> + +<h4 id="this_on_the_objects_prototype_chain"><code>this</code> on the object's prototype chain</h4> + +<p>The same notion holds true for methods defined somewhere on the object's prototype chain. If the method is on an object's prototype chain, <code>this</code> refers to the object the method was called on, as if the method were on the object.</p> + +<pre class="brush:js">var o = {f: function() { return this.a + this.b; }}; +var p = Object.create(o); +p.a = 1; +p.b = 4; + +console.log(p.f()); // 5 +</pre> + +<p>In this example, the object assigned to the variable <code>p</code> doesn't have its own <code>f</code> property, it inherits it from its prototype. But it doesn't matter that the lookup for <code>f</code> eventually finds a member with that name on <code>o</code>; the lookup began as a reference to <code>p.f</code>, so <code>this</code> inside the function takes the value of the object referred to as <code>p</code>. That is, since <code>f</code> is called as a method of <code>p</code>, its <code>this</code> refers to <code>p</code>. This is an interesting feature of JavaScript's prototype inheritance.</p> + +<h4 id="this_with_a_getter_or_setter"><code>this</code> with a getter or setter</h4> + +<p>Again, the same notion holds true when a function is invoked from a getter or a setter. A function used as getter or setter has its <code>this</code> bound to the object from which the property is being set or gotten.</p> + +<pre class="brush:js">function sum() { + return this.a + this.b + this.c; +} + +var o = { + a: 1, + b: 2, + c: 3, + get average() { + return (this.a + this.b + this.c) / 3; + } +}; + +Object.defineProperty(o, 'sum', { + get: sum, enumerable: true, configurable: true}); + +console.log(o.average, o.sum); // 2, 6 +</pre> + +<h3 id="As_a_constructor">As a constructor</h3> + +<p>When a function is used as a constructor (with the {{jsxref("Operators/new", "new")}} keyword), its <code>this</code> is bound to the new object being constructed.</p> + +<div class="note"> +<p>While the default for a constructor is to return the object referenced by <code>this</code>, it can instead return some other object (if the return value isn't an object, then the <code>this</code> object is returned).</p> +</div> + +<pre class="brush:js">/* + * Constructors work like this: + * + * function MyConstructor(){ + * // Actual function body code goes here. + * // Create properties on |this| as + * // desired by assigning to them. E.g., + * this.fum = "nom"; + * // et cetera... + * + * // If the function has a return statement that + * // returns an object, that object will be the + * // result of the |new| expression. Otherwise, + * // the result of the expression is the object + * // currently bound to |this| + * // (i.e., the common case most usually seen). + * } + */ + +function C() { + this.a = 37; +} + +var o = new C(); +console.log(o.a); // 37 + + +function C2() { + this.a = 37; + return {a: 38}; +} + +o = new C2(); +console.log(o.a); // 38 +</pre> + +<p>In the last example (<code>C2</code>), because an object was returned during construction, the new object that <code>this</code> was bound to simply gets discarded. (This essentially makes the statement "<code>this.a = 37;</code>" dead code. It's not exactly dead because it gets executed, but it can be eliminated with no outside effects.)</p> + +<h3 id="As_a_DOM_event_handler">As a DOM event handler</h3> + +<p>When a function is used as an event handler, its <code>this</code> is set to the element on which the listener is placed (some browsers do not follow this convention for listeners added dynamically with methods other than <a href="/en-US/docs/Web/API/EventTarget/addEventListener" title="The EventTarget method addEventListener() sets up a function that will be called whenever the specified event is delivered to the target."><code>addEventListener()</code></a>).</p> + +<pre class="brush:js">// When called as a listener, turns the related element blue +function bluify(e) { + // Always true + console.log(this === e.currentTarget); + // true when currentTarget and target are the same object + console.log(this === e.target); + this.style.backgroundColor = '#A5D9F3'; +} + +// Get a list of every element in the document +var elements = document.getElementsByTagName('*'); + +// Add bluify as a click listener so when the +// element is clicked on, it turns blue +for (var i = 0; i < elements.length; i++) { + elements[i].addEventListener('click', bluify, false); +}</pre> + +<h3 id="In_an_inline_event_handler">In an inline event handler</h3> + +<p>When the code is called from an inline <a href="/en-US/docs/Web/Guide/Events/Event_handlers">on-event handler</a>, its <code>this</code> is set to the DOM element on which the listener is placed:</p> + +<pre class="brush:js"><button onclick="alert(this.tagName.toLowerCase());"> + Show this +</button> +</pre> + +<p>The above alert shows <code>button</code>. Note however that only the outer code has its <code>this</code> set this way:</p> + +<pre class="brush:js"><button onclick="alert((function() { return this; })());"> + Show inner this +</button> +</pre> + +<p>In this case, the inner function's <code>this</code> isn't set so it returns the global/window object (i.e. the default object in non–strict mode where <code>this</code> isn't set by the call).</p> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-this-keyword', 'The this keyword')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.this")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode">Strict mode</a></li> + <li><a href="https://dmitripavlutin.com/gentle-explanation-of-this-in-javascript/">Gentle explanation of 'this' keyword in JavaScript</a></li> + <li>Getting the global context: {{jsxref("globalThis")}}</li> +</ul> diff --git a/files/vi/web/javascript/reference/operators/typeof/index.html b/files/vi/web/javascript/reference/operators/typeof/index.html new file mode 100644 index 0000000000..e949879669 --- /dev/null +++ b/files/vi/web/javascript/reference/operators/typeof/index.html @@ -0,0 +1,271 @@ +--- +title: typeof +slug: Web/JavaScript/Reference/Operators/typeof +translation_of: Web/JavaScript/Reference/Operators/typeof +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>Phương thức <strong><code>typeof</code></strong> trả về kiểu dữ liệu của đối tượng nào đó.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-typeof.html")}}</div> + + + +<h2 id="Cú_pháp">Cú pháp</h2> + +<p>Phương thức <code>typeof</code> được theo sau bởi toán hạng operand:</p> + +<pre class="syntaxbox">typeof <em>operand +</em>typeof(<em>operand</em>) +</pre> + +<h3 id="Các_tham_số">Các tham số</h3> + +<dl> + <dt><code>operand</code></dt> + <dd>Là một đối tượng cần kiểu tra kiểu dữ liệu hoặc một biểu thức đại điện cho đối tượng.</dd> +</dl> + +<h2 id="Định_nghĩa">Định nghĩa</h2> + +<p>Bảng tóm tắt bên dưới mô tả các giá trị có thể trả về của <code>typeof</code>. Xem thêm thông tin tại trang <a href="/en-US/docs/Web/JavaScript/Data_structures">JavaScript data structure</a>.</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Type</th> + <th scope="col">Result</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{glossary("Undefined")}}</td> + <td><code>"undefined"</code></td> + </tr> + <tr> + <td>{{glossary("Null")}}</td> + <td><code>"object"</code> (see {{anch("null", "below")}})</td> + </tr> + <tr> + <td>{{glossary("Boolean")}}</td> + <td><code>"boolean"</code></td> + </tr> + <tr> + <td>{{glossary("Number")}}</td> + <td><code>"number"</code></td> + </tr> + <tr> + <td>{{glossary("BigInt")}}</td> + <td><code>"bigint"</code></td> + </tr> + <tr> + <td>{{glossary("String")}}</td> + <td><code>"string"</code></td> + </tr> + <tr> + <td>{{glossary("Symbol")}} (new in ECMAScript 2015)</td> + <td><code>"symbol"</code></td> + </tr> + <tr> + <td>Host object (provided by the JS environment)</td> + <td><em>Implementation-dependent</em></td> + </tr> + <tr> + <td>{{glossary("Function")}} object (implements [[Call]] in ECMA-262 terms)</td> + <td><code>"function"</code></td> + </tr> + <tr> + <td>Any other object</td> + <td><code>"object"</code></td> + </tr> + </tbody> +</table> + +<h2 id="Các_ví_dụ">Các ví dụ</h2> + +<pre class="brush:js">// Numbers +typeof 37 === 'number'; +typeof 3.14 === 'number'; +typeof(42) === 'number'; +typeof Math.LN2 === 'number'; +typeof Infinity === 'number'; +typeof NaN === 'number'; // Mặc dù "Not-A-Number" nhưng lại là number :) +typeof Number('1') === 'number'; // Number ép kiểu chuỗi thành kiểu number + +typeof 42n === 'bigint'; + + +// Strings +typeof '' === 'string'; +typeof 'bla' === 'string'; +typeof `template literal` === 'string'; +typeof '1' === 'string'; // 1 là number nhưng khi nằm trong ngoặc '' sẽ thành kiểu string +typeof (typeof 1) === 'string'; // typeof 1 sẽ trả về chữ number, bạn tự hiểu được hen +typeof String(1) === 'string'; // String sẽ đổi kiểu số 1 từ number thành string + +// Booleans +typeof true === 'boolean'; +typeof false === 'boolean'; +typeof Boolean(1) === 'boolean'; // Boolean() will convert values based on if they're truthy or falsy +typeof !!(1) === 'boolean'; // two calls of the ! (logical NOT) operator are equivalent to Boolean() + + +// Symbols +typeof Symbol() === 'symbol' +typeof Symbol('foo') === 'symbol' +typeof Symbol.iterator === 'symbol' + + +// Undefined +typeof undefined === 'undefined'; +typeof declaredButUndefinedVariable === 'undefined'; +typeof undeclaredVariable === 'undefined'; + + +// Objects +typeof {a: 1} === 'object'; + +// use <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray">Array.isArray</a> or Object.prototype.toString.call +// to differentiate regular objects from arrays +typeof [1, 2, 4] === 'object'; + +typeof new Date() === 'object'; +typeof /regex/ === 'object'; // See Regular expressions section for historical results + + +// The following are confusing, dangerous, and wasteful. Avoid them. +typeof new Boolean(true) === 'object'; +typeof new Number(1) === 'object'; +typeof new String('abc') === 'object'; + + +// Functions +typeof function() {} === 'function'; +typeof class C {} === 'function'; +typeof Math.sin === 'function'; +</pre> + +<h2 id="Additional_information">Additional information</h2> + +<h3 id="null"><code>null</code></h3> + +<pre class="brush:js">// This stands since the beginning of JavaScript +typeof null === 'object'; +</pre> + +<p>In the first implementation of JavaScript, JavaScript values were represented as a type tag and a value. The type tag for objects was 0. <code>null</code> was represented as the NULL pointer (0x00 in most platforms). Consequently, null had 0 as type tag, hence the "object" <code>typeof</code> return value. (<a href="http://www.2ality.com/2013/10/typeof-null.html">reference</a>)</p> + +<p>A fix was proposed for ECMAScript (via an opt-in), but <a class="external" href="https://web.archive.org/web/20160331031419/http://wiki.ecmascript.org:80/doku.php?id=harmony:typeof_null">was rejected</a>. It would have resulted in <code>typeof null === 'null'</code>.</p> + +<h3 id="Using_new_operator">Using <code>new</code> operator</h3> + +<pre class="brush:js">// All constructor functions, with the exception of the Function constructor, will always be typeof 'object' +var str = new String('String'); +var num = new Number(100); + +typeof str; // It will return 'object' +typeof num; // It will return 'object' + +var func = new Function(); + +typeof func; // It will return 'function' +</pre> + +<h3 id="Need_for_parentheses_in_Syntax">Need for parentheses in Syntax</h3> + +<pre class="brush:js">// Parentheses can be used for determining the data type of expressions. +var iData = 99; + +typeof iData + ' Wisen'; // 'number Wisen' +typeof (iData + ' Wisen'); // 'string' +</pre> + +<h3 id="Regular_expressions">Regular expressions</h3> + +<p>Callable regular expressions were a non-standard addition in some browsers.</p> + +<pre class="brush:js">typeof /s/ === 'function'; // Chrome 1-12 Non-conform to ECMAScript 5.1 +typeof /s/ === 'object'; // Firefox 5+ Conform to ECMAScript 5.1 +</pre> + +<h3 id="Errors">Errors</h3> + +<p>Before ECMAScript 2015, <code>typeof</code> was always guaranteed to return a string for any operand it was supplied with. Even with undeclared identifiers, <code>typeof</code> will return <code>'undefined'</code>. Using <code>typeof</code> could never generate an error.</p> + +<p>But with the addition of block-scoped {{jsxref("Statements/let", "let")}} and {{jsxref("Statements/const")}} using <code>typeof</code> on <code>let</code> and <code>const</code> variables (or using <code>typeof</code> on a <code>class</code>) in a block before they are declared will throw a {{jsxref("ReferenceError")}}. Block scoped variables are in a "<a href="/en-US/docs/Web/JavaScript/Reference/Statements/let#The_temporal_dead_zone_and_typeof">temporal dead zone</a>" from the start of the block until the initialization is processed, during which, it will throw an error if accessed.</p> + +<pre class="brush: js">typeof undeclaredVariable === 'undefined'; + +typeof newLetVariable; // ReferenceError +typeof newConstVariable; // ReferenceError +typeof newClass; // ReferenceError + +let newLetVariable; +const newConstVariable = 'hello'; +class newClass{};</pre> + +<h3 id="Exceptions">Exceptions</h3> + +<p>All current browsers expose a non-standard host object {{domxref("document.all")}} with type <code>undefined</code>.</p> + +<pre class="brush:js">typeof document.all === 'undefined'; +</pre> + +<p>Although the specification allows custom type tags for non-standard exotic objects, it requires those type tags to be different from the predefined ones. The case of <code>document.all</code> having type <code>'undefined'</code> is classified in the web standards as a "willful violation" of the original ECMA JavaScript standard.</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('ESDraft', '#sec-typeof-operator', 'The typeof Operator')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-typeof-operator', 'The typeof Operator')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-11.4.3', 'The typeof Operator')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES3', '#sec-11.4.3', 'The typeof Operator')}}</td> + <td>{{Spec2('ES3')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES1', '#sec-11.4.3', 'The typeof Operator')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition. Implemented in JavaScript 1.1.</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.operators.typeof")}}</p> + +<h2 id="IE-specific_notes">IE-specific notes</h2> + +<p>On IE 6, 7, and 8 a lot of host objects are objects and not functions. For example:</p> + +<pre class="brush: js">typeof alert === 'object'</pre> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{jsxref("Operators/instanceof", "instanceof")}}</li> + <li><a href="http://es-discourse.com/t/why-typeof-is-no-longer-safe/15">Why typeof is no longer "safe"</a></li> + <li><a href="https://github.com/tc39/ecma262/issues/668">document.all willful violation of the standard</a></li> +</ul> |