From 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:43:23 -0500 Subject: initial commit --- .../operators/arithmetic_operators/index.html | 312 ++++++++++++++ .../operators/conditional_operator/index.html | 119 +++++ .../reference/operators/delete/index.html | 292 +++++++++++++ .../reference/operators/function/index.html | 175 ++++++++ .../web/javascript/reference/operators/index.html | 298 +++++++++++++ .../operators/operator_precedence/index.html | 477 +++++++++++++++++++++ .../reference/operators/super/index.html | 226 ++++++++++ .../javascript/reference/operators/this/index.html | 382 +++++++++++++++++ .../reference/operators/typeof/index.html | 271 ++++++++++++ 9 files changed, 2552 insertions(+) create mode 100644 files/vi/web/javascript/reference/operators/arithmetic_operators/index.html create mode 100644 files/vi/web/javascript/reference/operators/conditional_operator/index.html create mode 100644 files/vi/web/javascript/reference/operators/delete/index.html create mode 100644 files/vi/web/javascript/reference/operators/function/index.html create mode 100644 files/vi/web/javascript/reference/operators/index.html create mode 100644 files/vi/web/javascript/reference/operators/operator_precedence/index.html create mode 100644 files/vi/web/javascript/reference/operators/super/index.html create mode 100644 files/vi/web/javascript/reference/operators/this/index.html create mode 100644 files/vi/web/javascript/reference/operators/typeof/index.html (limited to 'files/vi/web/javascript/reference/operators') 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 +--- +
{{jsSidebar("Operators")}}
+ +

Toán tử số học 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 (/).

+ +
{{EmbedInteractiveExample("pages/js/expressions-arithmetic.html")}}
+ + + +

Cộng (+)

+ +

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.

+ +

Cú pháp

+ +
Toán tử: x + y
+
+ +

Examples

+ +
// 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"
+
+ +

Trừ (-)

+ +

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.

+ +

Cú pháp

+ +
Toán tử: x - y
+
+ +

Ví dụ

+ +
5 - 3 // 2
+3 - 5 // -2
+'foo' - 3 // NaN
+ +

Chia (/)

+ +

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.

+ +

Cú pháp

+ +
Toán tử: x / y
+
+ +

Ví dụ

+ +
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
+ +

Nhân (*)

+ +

Toán tử nhân xuất ra tích của các toán hạng.

+ +

Cú pháp

+ +
Toán tử: x * y
+
+ +

Ví dụ

+ +
2 * 2 // 4
+-2 * 2 // -4
+Infinity * 0 // NaN
+Infinity * Infinity // Infinity
+'foo' * 2 // NaN
+
+ +

Chia lấy dư (%)

+ +

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.

+ +

Cú pháp

+ +
Toán tử: var1 % var2
+
+ +

Ví dụ

+ +
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
+
+ +

Luỹ thừa (**)

+ +

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à, var1var2, như đã khẳng định trước đó, với var1var2 là biến số. Toán tử luỹ thừa là dạng liên hợp phải. a ** b ** c bằng với a ** (b ** c).

+ +

Cú pháp

+ +
Toán tử: var1 ** var2
+
+ +

Ghi chú

+ +

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 (+/-/~/!/delete/void/typeof) ngay trước cơ số.

+ +
-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.
+
+ +

Ví dụ

+ +
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
+
+ +

To invert the sign of the result of an exponentiation expression:

+ +
-(2 ** 2) // -4
+
+ +

Để ép cơ số trong biểu thức luỹ thừa thành số âm:

+ +
(-2) ** 2 // 4
+
+ +
+

Ghi chú: JavaScript cũng có toán tử thao tác bit ^ (XOR). **^ khác nhau (chẳng hạn: 2 ** 3 === 8 trong khi 2 ^ 3 === 1.)

+
+ +

 

+ +

Tăng (++)

+ +

 

+ +

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ị.

+ + + +

Cú pháp

+ +
Toán tử: x++ hoặc ++x
+
+ +

Ví dụ

+ +
// Hậu tố
+var x = 3;
+y = x++; // y = 3, x = 4
+
+// Tiền tố
+var a = 2;
+b = ++a; // a = 3, b = 3
+
+ +

Giảm (--)

+ +

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ị.

+ + + +

Cú pháp

+ +
Toán tử: x-- hoặc --x
+
+ +

Ví dụ

+ +
// Hậu tố
+var x = 3;
+y = x--; // y = 3, x = 2
+
+// Tiền tố
+var a = 2;
+b = --a; // a = 1, b = 1
+
+ +

Phủ định một ngôi (-)

+ +

Toán tử phủ định một ngôi đứng trước và phủ định toán hạng của nó.

+ +

Cú pháp

+ +
Toán tử: -x
+
+ +

Ví dụ

+ +
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
+
+ +

Cộng một ngôi (+)

+ +

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ư true, false, và null. 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 NaN.

+ +

Cú pháp

+ +
Toán tử: +x
+
+ +

Ví dụ

+ +
+3     // 3
++'3'   // 3
++true  // 1
++false // 0
++null  // 0
++function(val){  return val } // NaN
+
+ +

Đặc tả

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Đặc tảTrạng tháiBình luận
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-11.3')}}{{Spec2('ES5.1')}}Defined in several sections of the specification: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES2015', '#sec-postfix-expressions')}}{{Spec2('ES2015')}}Defined in several sections of the specification: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES2016', '#sec-postfix-expressions')}}{{Spec2('ES2016')}}Added Exponentiation operator.
{{SpecName('ES2017', '#sec-postfix-expressions')}}{{Spec2('ES2017')}} 
{{SpecName('ESDraft', '#sec-additive-operators')}}{{Spec2('ESDraft')}} 
+ +

Tương thích trình duyệt

+ + + +

{{Compat("javascript.operators.arithmetic")}}

+ +

Đọc thêm

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

Toán tử điều kiện (ba ngôi) 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 if.

+ +
{{EmbedInteractiveExample("pages/js/expressions-conditionaloperators.html")}}
+ + + +

Cú pháp

+ +
condition ? exprT : exprF 
+ +

Tham số

+ +
+
condition
+
Biểu thức mà giá trị của nó được dùng như điều kiện.
+
+ +
+
exprT, exprF
+
Biểu thức với giá trị có kiểu bất kỳ.
+
+ +

Mô tả

+ +

Nếu condition có thể chuyển đổi thànhtrue (hay là {{Glossary("truthy")}}), toán tử trả về giá trị của exprT; ngược lại (khi condition là {{Glossary("falsy")}}), nó trả về giá trị của exprF.

+ +

(Trong cả hai trường hợp, biểu thức còn lại đều không được duyệt tới.)

+ +

Ngoài false ra, các biểu thức falsy có thể xảy ra bao gồm: nullNaN0, xâu ký tự rỗng (""), và undefined. Nếu condition 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à exprF.

+ +

Ví dụ đơn giản:

+ +
var age = 26;
+var beverage = (age >= 21) ? "Beer" : "Juice";
+console.log(beverage); // "Beer"
+
+ +

Thường dùng để xử lý giá trị null:

+ +
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"​​​​​
+
+ +

Điều kiện nối tiế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 if … else if … else if … else nối tiếp nhau:

+ +
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; }
+}
+
+ +

Đặc tả

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Đặc tảTrạng tháiBình luận
{{SpecName('ESDraft', '#sec-conditional-operator', 'Conditional Operator')}}{{Spec2('ESDraft')}} 
{{SpecName('ES6', '#sec-conditional-operator', 'Conditional Operator')}}{{Spec2('ES6')}} 
{{SpecName('ES5.1', '#sec-11.12', 'The conditional operator')}}{{Spec2('ES5.1')}} 
{{SpecName('ES1', '#sec-11.12', 'The conditional operator')}}{{Spec2('ES1')}}Định nghĩa lần đầu. Cài đặt trong JavaScript 1.0.
+ +

Tương thích trình duyệt

+ + + +

{{Compat("javascript.operators.conditional")}}

+ +

Xem thêm

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

Toán tử delete 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.

+ +
{{EmbedInteractiveExample("pages/js/expressions-deleteoperator.html")}}
+ + + +

Cú pháp

+ +
delete expression 
+ +

với expression thực thi thành tham chiếu đến thuộc tính nào đó, tức là:

+ +
delete object.property
+delete object['property']
+
+ +

Tham số

+ +
+
object
+
Tên object, hoặc biểu thức thực thi tới object.
+
property
+
Thuộc tính muốn xoá.
+
+ +

Giá trị trả về

+ +

true cho mọi trường hợp trừ khi thuộc tính là own non-configurable, trong trường hợp đó, trả về false trong chế độ non-strict.

+ +

Ngoại lệ

+ +

Quăng {{jsxref("TypeError")}} trong chế độ strict nếu thuộc tính là own non-configurable.

+ +

Mô tả

+ +

Khác với suy nghĩ của nhiều người, toán tử delete không 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 quản lý bộ nhớ để biết thêm chi tiết.

+ +

Toán tử delete loại bỏ thuộc tính xác định trong object. Nếu xoá thành công, nó sẽ trả về true, ngoài ra thì false. Tuy nhiên, hãy lưu ý những kịch bản có thể xảy đến sau đây:

+ + + +

Snippet sau đưa ra ví dụ đơn giản:

+ +
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
+
+ +

Thuộc tính không-thể-cấu-hình

+ +

Khi một thuộc tính được đánh dấu không-thể-cấu-hình, delete không có tác dụng nào, và sẽ trả về false. Trong chế độ strict, lỗi TypeError sẽ nhảy ra.

+ +
var Employee = {};
+Object.defineProperty(Employee, 'name', {configurable: false});
+
+console.log(delete Employee.name);  // trả về false
+
+ +

{{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ử delete:

+ +
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,
+//                  configurable: false}
+
+// 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
+ +

Trong chế độ strict, ngoại lệ sẽ quăng ra.

+ +

Chế độ strict và non-strict

+ +

Khi ở trong chế độ strict, nếu delete đượ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")}}.

+ +

Bất cứ biến nào được định nghĩa với var đều được đánh dấu là không-thể-cấu-hình. Trong ví dụ sau đây, salary là không-thể-cấu-hình và không thể xoá. Trong chế độ non-strict, phép toán delete sẽ trả về false.

+ +
function Employee() {
+  delete salary;
+  var salary;
+}
+
+Employee();
+
+ +

Cùng xem mã nguồn tương tự hoạt động ra sao trong chế độ strict nhé. Thay vì trả về false, SyntaxError được quăng ra.

+ +
"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
+
+ +

Ví dụ

+ +
// 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
+
+// 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
+}
+
+ +

delete và prototype chain

+ +

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:

+ +
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
+ +

Xoá phần tử mảng

+ +

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.

+ +

Khi toán tử delete loại bỏ một phần tử mảng, phần tử đó không còn trong mảng. Trong ví dụ sau, trees[3] bị xoá bởi delete.

+ +
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
+delete trees[3];
+if (3 in trees) {
+    // không thực thi đoạn code này
+}
+ +

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 undefined thay vì toán tử delete. Trong ví dụ sau, trees[3] được gán giá trị undefined, nhưng phần tử mảng vẫn tồn tại:

+ +
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
+trees[3] = undefined;
+if (3 in trees) {
+    // đoạn code trong này sẽ chạy
+}
+ +

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 {{jsxref("Array.splice", "splice")}}. Trong ví dụ sau, trees[3] bị xoá bỏ hoàn toàn khỏi mảng thông qua {{jsxref("Array.splice", "splice")}}:

+ +
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
+trees.splice(3,1);
+console.log(trees); // ["redwood", "bay", "cedar", "maple"]
+
+ +

Đặc Đặc tả

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-delete-operator', 'The delete Operator')}}{{Spec2('ESDraft')}} 
{{SpecName('ES6', '#sec-delete-operator', 'The delete Operator')}}{{Spec2('ES6')}} 
{{SpecName('ES5.1', '#sec-11.4.1', 'The delete Operator')}}{{Spec2('ES5.1')}} 
{{SpecName('ES1', '#sec-11.4.1', 'The delete Operator')}}{{Spec2('ES1')}}Định nghĩa lần đầu. Cài đặt trong JavaScript 1.2.
+ +

Trình duyệt hỗ trợ

+ + + +

{{Compat("javascript.operators.delete")}}

+ +

Ghi chú Cross-browser

+ +

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 delete 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 value is indeed set to undefined, if one later adds back a property with the same name, the property will be iterated in its old position--not at the end of the iteration sequence as one might expect after having deleted the property and then added it back.

+ +

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.

+ +

Xem thêm

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

Từ khóa function (hàm) có thể dùng để định nghĩa chức năng bên trong một biểu thức.

+ +

Cú pháp

+ +
var myFunction = function [name]([param1[, param2[, ..., paramN]]]) {
+   statements
+};
+ +

Tham số

+ +
+
name
+
Tên hàm. Có thể bỏ qua, trong trường hợp chức năng đó là vô danh. Nó mô tả chính xác nhiệm vụ mà hàm sẽ làm.
+
paramN
+
Tên các đối số truyền vào.
+
statements
+
Các câu lệnh xử lý các đối số paramN truyền vào.
+
+ +

Mô tả

+ +

Một biểu thức chức năng (function) is very similar to and has almost the same syntax as a function statement (see function statement for details). The main difference between a function expression and a function statement is the function name, which can be omitted in function expressions to create anonymous functions. A function expression can be used as a IIFE (Immediately Invoked Function Expression) which runs as soon as it is defined. See also the chapter about functions for more information.

+ +

Function expression hoisting

+ +

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:

+ +
notHoisted(); // TypeError: notHoisted is not a function
+
+var notHoisted = function() {
+   console.log('bar');
+};
+
+ +

Examples

+ +

The following example defines an unnamed function and assigns it to x. The function returns the square of its argument:

+ +
var x = function(y) {
+   return y * y;
+};
+
+ +

Named function expression

+ +

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 arguments.callee property.

+ +
var math = {
+  'factorial': function factorial(n) {
+    if (n <= 1)
+      return 1;
+    return n * factorial(n - 1);
+  }
+};
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-function-definitions', 'Function definitions')}}{{Spec2('ESDraft')}} 
{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}{{Spec2('ES6')}} 
{{SpecName('ES5.1', '#sec-13', 'Function definition')}}{{Spec2('ES5.1')}} 
{{SpecName('ES3', '#sec-13', 'Function definition')}}{{Spec2('ES3')}}Initial definition. Implemented in JavaScript 1.5.
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Trailing comma in parameters{{CompatUnknown}}{{CompatGeckoDesktop("52.0")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Trailing comma in parameters{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("52.0")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

This chapter documents all the JavaScript language operators, expressions and keywords.

+ +

Expressions and operators by category

+ +

For an alphabetical listing see the sidebar on the left.

+ +

Primary expressions

+ +

Basic keywords and general expressions in JavaScript.

+ +
+
{{jsxref("Operators/this", "this")}}
+
The this keyword refers to the function's execution context.
+
{{jsxref("Operators/function", "function")}}
+
The function keyword defines a function expression.
+
{{jsxref("Operators/class", "class")}}
+
The class keyword defines a class expression.
+
{{jsxref("Operators/function*", "function*")}}
+
The function* keyword defines a generator function expression.
+
{{jsxref("Operators/yield", "yield")}}
+
Pause and resume a generator function.
+
{{jsxref("Operators/yield*", "yield*")}}
+
Delegate to another generator function or iterable object.
+
{{jsxref("Global_Objects/Array", "[]")}}
+
Array initializer/literal syntax.
+
{{jsxref("Operators/Object_initializer", "{}")}}
+
Object initializer/literal syntax.
+
{{jsxref("Global_Objects/RegExp", "/ab+c/i")}}
+
Regular expression literal syntax.
+
{{jsxref("Operators/Grouping", "( )")}}
+
Grouping operator.
+
+ +

Left-hand-side expressions

+ +

Left values are the destination of an assignment.

+ +
+
{{jsxref("Operators/Property_accessors", "Property accessors", "", 1)}}
+
Member operators provide access to a property or method of an object
+ (object.property and object["property"]).
+
{{jsxref("Operators/new", "new")}}
+
The new operator creates an instance of a constructor.
+
new.target
+
In constructors, new.target refers to the constructor that was invoked by {{jsxref("Operators/new", "new")}}.
+
{{jsxref("Operators/super", "super")}}
+
The super keyword calls the parent constructor.
+
{{jsxref("Operators/Spread_operator", "...obj")}}
+
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.
+
+ +

Increment and decrement

+ +

Postfix/prefix increment and postfix/prefix decrement operators.

+ +
+
{{jsxref("Operators/Arithmetic_Operators", "A++", "#Increment")}}
+
Postfix increment operator.
+
{{jsxref("Operators/Arithmetic_Operators", "A--", "#Decrement")}}
+
Postfix decrement operator.
+
{{jsxref("Operators/Arithmetic_Operators", "++A", "#Increment")}}
+
Prefix increment operator.
+
{{jsxref("Operators/Arithmetic_Operators", "--A", "#Decrement")}}
+
Prefix decrement operator.
+
+ +

Unary operators

+ +

A unary operation is operation with only one operand.

+ +
+
{{jsxref("Operators/delete", "delete")}}
+
The delete operator deletes a property from an object.
+
{{jsxref("Operators/void", "void")}}
+
The void operator discards an expression's return value.
+
{{jsxref("Operators/typeof", "typeof")}}
+
The typeof operator determines the type of a given object.
+
{{jsxref("Operators/Arithmetic_Operators", "+", "#Unary_plus")}}
+
The unary plus operator converts its operand to Number type.
+
{{jsxref("Operators/Arithmetic_Operators", "-", "#Unary_negation")}}
+
The unary negation operator converts its operand to Number type and then negates it.
+
{{jsxref("Operators/Bitwise_Operators", "~", "#Bitwise_NOT")}}
+
Bitwise NOT operator.
+
{{jsxref("Operators/Logical_Operators", "!", "#Logical_NOT")}}
+
Logical NOT operator.
+
+ +

Arithmetic operators

+ +

Arithmetic operators take numerical values (either literals or variables) as their operands and return a single numerical value.

+ +
+
{{jsxref("Operators/Arithmetic_Operators", "+", "#Addition")}}
+
Addition operator.
+
{{jsxref("Operators/Arithmetic_Operators", "-", "#Subtraction")}}
+
Subtraction operator.
+
{{jsxref("Operators/Arithmetic_Operators", "/", "#Division")}}
+
Division operator.
+
{{jsxref("Operators/Arithmetic_Operators", "*", "#Multiplication")}}
+
Multiplication operator.
+
{{jsxref("Operators/Arithmetic_Operators", "%", "#Remainder")}}
+
Remainder operator.
+
+ +
+
{{jsxref("Operators/Arithmetic_Operators", "**", "#Exponentiation")}}
+
Exponentiation operator.
+
+ +

Relational operators

+ +

A comparison operator compares its operands and returns a Boolean value based on whether the comparison is true.

+ +
+
{{jsxref("Operators/in", "in")}}
+
The in operator determines whether an object has a given property.
+
{{jsxref("Operators/instanceof", "instanceof")}}
+
The instanceof operator determines whether an object is an instance of another object.
+
{{jsxref("Operators/Comparison_Operators", "<", "#Less_than_operator")}}
+
Less than operator.
+
{{jsxref("Operators/Comparison_Operators", ">", "#Greater_than_operator")}}
+
Greater than operator.
+
{{jsxref("Operators/Comparison_Operators", "<=", "#Less_than_or_equal_operator")}}
+
Less than or equal operator.
+
{{jsxref("Operators/Comparison_Operators", ">=", "#Greater_than_or_equal_operator")}}
+
Greater than or equal operator.
+
+ +
+

Note: => is not an operator, but the notation for Arrow functions.

+
+ +

Equality operators

+ +

The result of evaluating an equality operator is always of type Boolean based on whether the comparison is true.

+ +
+
{{jsxref("Operators/Comparison_Operators", "==", "#Equality")}}
+
Equality operator.
+
{{jsxref("Operators/Comparison_Operators", "!=", "#Inequality")}}
+
Inequality operator.
+
{{jsxref("Operators/Comparison_Operators", "===", "#Identity")}}
+
Identity operator.
+
{{jsxref("Operators/Comparison_Operators", "!==", "#Nonidentity")}}
+
Nonidentity operator.
+
+ +

Bitwise shift operators

+ +

Operations to shift all bits of the operand.

+ +
+
{{jsxref("Operators/Bitwise_Operators", "<<", "#Left_shift")}}
+
Bitwise left shift operator.
+
{{jsxref("Operators/Bitwise_Operators", ">>", "#Right_shift")}}
+
Bitwise right shift operator.
+
{{jsxref("Operators/Bitwise_Operators", ">>>", "#Unsigned_right_shift")}}
+
Bitwise unsigned right shift operator.
+
+ +

Binary bitwise operators

+ +

Bitwise operators treat their operands as a set of 32 bits (zeros and ones) and return standard JavaScript numerical values.

+ +
+
{{jsxref("Operators/Bitwise_Operators", "&", "#Bitwise_AND")}}
+
Bitwise AND.
+
{{jsxref("Operators/Bitwise_Operators", "|", "#Bitwise_OR")}}
+
Bitwise OR.
+
{{jsxref("Operators/Bitwise_Operators", "^", "#Bitwise_XOR")}}
+
Bitwise XOR.
+
+ +

Binary logical operators

+ +

Logical operators are typically used with boolean (logical) values, and when they are, they return a boolean value.

+ +
+
{{jsxref("Operators/Logical_Operators", "&&", "#Logical_AND")}}
+
Logical AND.
+
{{jsxref("Operators/Logical_Operators", "||", "#Logical_OR")}}
+
Logical OR.
+
+ +

Conditional (ternary) operator

+ +
+
{{jsxref("Operators/Conditional_Operator", "(condition ? ifTrue : ifFalse)")}}
+
+

The conditional operator returns one of two values based on the logical value of the condition.

+
+
+ +

Assignment operators

+ +

An assignment operator assigns a value to its left operand based on the value of its right operand.

+ +
+
{{jsxref("Operators/Assignment_Operators", "=", "#Assignment")}}
+
Assignment operator.
+
{{jsxref("Operators/Assignment_Operators", "*=", "#Multiplication_assignment")}}
+
Multiplication assignment.
+
{{jsxref("Operators/Assignment_Operators", "/=", "#Division_assignment")}}
+
Division assignment.
+
{{jsxref("Operators/Assignment_Operators", "%=", "#Remainder_assignment")}}
+
Remainder assignment.
+
{{jsxref("Operators/Assignment_Operators", "+=", "#Addition_assignment")}}
+
Addition assignment.
+
{{jsxref("Operators/Assignment_Operators", "-=", "#Subtraction_assignment")}}
+
Subtraction assignment
+
{{jsxref("Operators/Assignment_Operators", "<<=", "#Left_shift_assignment")}}
+
Left shift assignment.
+
{{jsxref("Operators/Assignment_Operators", ">>=", "#Right_shift_assignment")}}
+
Right shift assignment.
+
{{jsxref("Operators/Assignment_Operators", ">>>=", "#Unsigned_right_shift_assignment")}}
+
Unsigned right shift assignment.
+
{{jsxref("Operators/Assignment_Operators", "&=", "#Bitwise_AND_assignment")}}
+
Bitwise AND assignment.
+
{{jsxref("Operators/Assignment_Operators", "^=", "#Bitwise_XOR_assignment")}}
+
Bitwise XOR assignment.
+
{{jsxref("Operators/Assignment_Operators", "|=", "#Bitwise_OR_assignment")}}
+
Bitwise OR assignment.
+
{{jsxref("Operators/Destructuring_assignment", "[a, b] = [1, 2]")}}
+ {{jsxref("Operators/Destructuring_assignment", "{a, b} = {a:1, b:2}")}}
+
+

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.

+
+
+ +

Comma operator

+ +
+
{{jsxref("Operators/Comma_Operator", ",")}}
+
The comma operator allows multiple expressions to be evaluated in a single statement and returns the result of the last expression.
+
+ +

Non-standard features

+ +
+
{{non-standard_inline}} {{jsxref("Operators/Legacy_generator_function", "Legacy generator function", "", 1)}}
+
The function 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.
+
{{non-standard_inline}} {{jsxref("Operators/Expression_closures", "Expression closures", "", 1)}}
+
The expression closure syntax is a shorthand for writing simple function.
+
{{non-standard_inline}} {{jsxref("Operators/Array_comprehensions", "[for (x of y) x]")}}
+
Array comprehensions.
+
{{non-standard_inline}} {{jsxref("Operators/Generator_comprehensions", "(for (x of y) y)")}}
+
Generator comprehensions.
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1', '#sec-11', 'Expressions')}}{{Spec2('ES1')}}Initial definition
{{SpecName('ES5.1', '#sec-11', 'Expressions')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-ecmascript-language-expressions', 'ECMAScript Language: Expressions')}}{{Spec2('ES6')}}New: Spread operator, destructuring assignment, super keyword.
{{SpecName('ESDraft', '#sec-ecmascript-language-expressions', 'ECMAScript Language: Expressions')}}{{Spec2('ESDraft')}} 
+ +

See also

+ + 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 +--- +
{{jsSidebar ("Toán tử")}}
+ +

Mức độ ưu tiên của toán tử xác định cách các toán tử được phân tích cú pháp liên quan đến nhau. 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.

+ +
{{EmbedInteractiveExample ("pages / js / expression-operatorprecedence.html")}}
+ + + +

Precedence And Associativity

+ +

Consider an expression describable by the representation below. Note that both OP1 and OP2 are fill-in-the-blanks for OPerators.

+ +
a OP1 b OP2 c
+ +

If OP1 and OP2 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.

+ +
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
+
+ +

Left-associativity (left-to-right) means that it is processed as (a OP1 b) OP2 c, while right-associativity (right-to-left) means it is interpreted as a OP1 (b OP2 c). Assignment operators are right-associative, so you can write:

+ +
a = b = 5; // same as writing a = (b = 5);
+
+ +

with the expected result that a and b get the value 5. This is because the assignment operator returns the value that is assigned. First, b is set to 5. Then the a is also set to 5, the return value of b = 5, aka right operand of the assignment.

+ +

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.

+ + + + + + + + + + + + + + + + +
CodeOutput
+
+function echo(name, num) {
+    console.log("Evaluating the " + name + " side");
+    return num;
+}
+// Notice the division operator (/)
+console.log(echo("left", 6) / echo("right", 2));
+
+
+
+Evaluating the left side
+Evaluating the right side
+3
+
+
+
+function echo(name, num) {
+    console.log("Evaluating the " + name + " side");
+    return num;
+}
+// Notice the exponentiation operator (**)
+console.log(echo("left", 2) ** echo("right", 3));
+
+
+Evaluating the left side
+Evaluating the right side
+8
+
+ +

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.

+ + + + + + + + + + + + + + + + + + + + +
CodeOutput
+
+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));
+
+
+
+Evaluating the left side
+Evaluating the middle side
+Evaluating the right side
+1
+
+
+
+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));
+
+
+
+Evaluating the left side
+Evaluating the middle side
+Evaluating the right side
+512
+
+
+
+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));
+
+
+Evaluating the left side
+Evaluating the middle side
+Evaluating the right side
+64
+
+ +

Looking at the code snippets above, 6 / 3 / 2 is the same as (6 / 3) / 2 because division is left-associative. Exponentiation, on the other hand, is right-associative, so 2 ** 3 ** 2 is the same as 2 ** (3 ** 2). Thus, doing (2 ** 3) ** 2 changes the order and results in the 64 seen in the table above.

+ +

Remember that precedence comes before associativity. So, mixing division and exponentiation, the exponentiation comes before the division. For example, 2 ** 3 / 3 ** 2 results in 0.8888888888888888 because it is the same as (2 ** 3) / (3 ** 2).

+ +

Note on grouping and short-circuiting

+ +

In the table below, Grouping is listed as having the highest precedence. However, that does not always mean the expression within the grouping symbols ( … ) is evaluated first, especially when it comes to short-circuiting.

+ +

Short-circuiting is jargon for conditional evaluation. For example, in the expression a && (b + c), if a is {{Glossary("falsy")}}, then the sub-expression (b + c) 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.

+ +
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`
+
+ +

Examples

+ +
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.
+
+ +

Table

+ +

The following table is ordered from highest (21) to lowest (1) precedence.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrecedenceOperator typeAssociativityIndividual operators
21{{jsxref("Operators/Grouping", "Grouping", "", 1)}}n/a( … )
20{{jsxref("Operators/Property_Accessors", "Member Access", "#Dot_notation", 1)}}left-to-right… . …
{{jsxref("Operators/Property_Accessors", "Computed Member Access","#Bracket_notation", 1)}}left-to-right… [ … ]
{{jsxref("Operators/new","new")}} (with argument list)n/anew … ( … )
Function Callleft-to-right… ( )
Optional chainingleft-to-right?.
19{{jsxref("Operators/new","new")}} (without argument list)right-to-leftnew …
18{{jsxref("Operators/Arithmetic_Operators","Postfix Increment","#Increment", 1)}}n/a… ++
{{jsxref("Operators/Arithmetic_Operators","Postfix Decrement","#Decrement", 1)}}… --
17Logical NOTright-to-left! …
Bitwise NOT~ …
Unary Plus+ …
Unary Negation- …
Prefix Increment++ …
Prefix Decrement-- …
{{jsxref("Operators/typeof", "typeof")}}typeof …
{{jsxref("Operators/void", "void")}}void …
{{jsxref ("Toán tử / xóa", "xóa")}}delete …
{{jsxref ("Toán tử / await", "await")}}await …
16Luỹ thừaphải sang trái… ** …
15Phép nhântrái sang phải… * …
Sư đoàn… / …
Phần còn lại… % …
14Thêm vàotrái sang phải… + …
Phép trừ… - …
13Dịch chuyển sang trái theo chiều bittrái sang phải… << …
Chuyển sang phải theo chiều bit… >> …
Chuyển sang phải không dấu bit… >>> …
12Ít hơntrái sang phải… < …
Nhỏ hơn hoặc bằng… <= …
Lớn hơn… > …
Lớn hơn hoặc bằng… >= …
{{jsxref ("Toán tử / trong", "trong")}}… in …
{{jsxref ("Toán tử / instanceof", "instanceof")}}… instanceof …
11Bình đẳngtrái sang phải… == …
Bất bình đẳng… != …
Bình đẳng nghiêm ngặt… === …
Bất bình đẳng nghiêm ngặt… !== …
10Bitwise VÀtrái sang phải… & …
9Bitwise XORtrái sang phải… ^ …
số 8Bitwise HOẶCtrái sang phải… | …
7Logic ANDtrái sang phải… && …
6Logic HOẶCtrái sang phải… || …
5Nhà điều hành liên kết Nullishtrái sang phải… ?? …
4Có điều kiệnphải sang trái… ? … : …
3Chuyển nhượngphải sang trái… = …
… += …
… -= …
… **= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
… &&= …
… ||= …
… ??= …
2{{jsxref ("Toán tử / lợi nhuận", "lợi nhuận")}}phải sang tráiyield …
{{jsxref ("Toán tử / lợi nhuận *", "lợi nhuận *")}}yield* …
1Dấu phẩy / Chuỗitrái sang phải… , …
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 +--- +
{{jsSidebar("Operators")}}
+ +

Từ khóa super được sử dụng để gọi các hàm trên đối tượng cha.

+ +

Các biểu thức super.prop và super[expr] là hợp lệ trong mọi định nghĩa phương thức ở cả classesobject literals.

+ +

Cú pháp

+ +
super([arguments]); // gọi hàm khởi tạo cha.
+super.functionOnParent([arguments]);
+
+ +

Mô tả

+ +

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.

+ +

Ví dụ

+ +

Sử dụng super trong classes

+ +

Đoạn code này lấy từ ví dụ về class (live demo).  super()  ở đây được gọi để tránh việc lặp lại các phần giống nhau của Rectangle và Square.

+ +
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;
+  }
+}
+ +

Gọi super trên các phương thức tĩnh

+ +

Bạn cũng có thể gọi super() trên các phương thức tĩnh.

+ +
class Human {
+  constructor() {}
+  static ping() {
+    return 'ping';
+  }
+}
+
+class Computer extends Human {
+  constructor() {}
+  static pingpong() {
+    return super.ping() + ' pong';
+  }
+}
+Computer.pingpong(); // 'ping pong'
+
+ +

Xóa các thuộc tính của super sẽ gây ra lỗi

+ +

Bạn không thể sử dụng thao tác deletesuper.prop hoặc super[expr] để xóa một thuộc tính của lớp cha, nó sẽ ném lỗi {{jsxref("ReferenceError")}}.

+ +
class Base {
+  constructor() {}
+  foo() {}
+}
+class Derived extends Base {
+  constructor() {}
+  delete() {
+    delete super.foo;
+  }
+}
+
+new Derived().delete(); // ReferenceError: invalid delete involving 'super'. 
+ +

Super.prop không thể ghi đè các thuộc tính non-writable

+ +

Khi định nghĩa các thuộc tính non-writable ví dụ {{jsxref("Object.defineProperty")}},  super không thể ghi đè giá trị của thuộc tính này.

+ +
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
+
+ +

Sử dụng super.prop trong object literals

+ +

Super cũng có thể được sử dụng trong khởi tạo đối tượng hoặc literal. Trong ví dụ này, 2 đối tượng định nghĩa một phương thức. Trong đối tượng thứ hai,  super 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 obj2 thành obj1, vì thế super có thể tìm method1 trên obj1.

+ +
var obj1 = {
+  method1() {
+    console.log("method 1");
+  }
+}
+
+var obj2 = {
+  method2() {
+   super.method1();
+  }
+}
+
+Object.setPrototypeOf(obj2, obj1);
+obj2.method2(); // logs "method 1"
+
+ +

Thông số kỹ thuật

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-super-keyword', 'super')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-super-keyword', 'super')}}{{Spec2('ESDraft')}} 
+ +

Khả năng tương thích của các trình duyệt

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
Tính năngChromeFirefox (Gecko)Internet ExplorerOperaSafari
Hỗ trợ cơ bản{{CompatChrome(42.0)}}{{CompatGeckoDesktop(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
Tính năngAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Hỗ trợ cơ bản{{CompatUnknown}}{{CompatChrome(42.0)}}{{CompatGeckoMobile(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(42.0)}}
+
+ +

Lưu ý cho Gecko

+ + + +

Xem thêm

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

Từ khoá this 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ế độ strict mode và non-strict mode.

+ +

Trong hầu hết các trường hợp, giá trị của this đượ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()")}} để thiết lập giá trị của this bất kể hàm được gọi thế nào, và ES2015 giới thiệu arrow functions mà không cung cấp ràng buộc với this của chúng (Nó sẽ giữ giá trị this của lexical context kèm theo).

+ +
{{EmbedInteractiveExample("pages/js/expressions-this.html")}}
+ + + +

Cú pháp

+ +
this
+ +

Giá trị

+ +

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.

+ +

Global context

+ +

Trong global context (bên ngoài các hàm), this tham chiếu tới global object cho dù trong strict mode hoặc không.

+ +
// 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"
+
+ +
+

Note: 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.

+
+ +

Function context

+ +

Bên trong một hàm, giá trị của this phụ thuộc vào cách gọi hàm.

+ +

Simple call

+ +

Vì đoạn mã sau không ở chế độ strict mode, và vì  giá trị của this không được thiết lập khi gọi, this mặc định là global objecct, đó là window trong trình duyệt. 

+ +
function f1() {
+  return this;
+}
+
+// In a browser:
+f1() === window; // true
+
+// In Node:
+f1() === global; // true
+ +

Tuy nhiên, trong chế độ strict mode, nếu giá trị của this không được thiết lập khi vào bối cảnh thực thi, nó sẽ giữ giá trị undefined, như ví dụ sau:

+ +
function f2() {
+  'use strict'; // see strict mode
+  return this;
+}
+
+f2() === undefined; // true
+
+ +
 Trong ví dụ thứ 2, this nên là {{jsxref("undefined")}}, bởi vì f2 đượ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ụ window.f2()). ?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ế độ strict mode. Như kết quả trên, chúng không trả về đối tượng window.
+ +

Để thiết lập giá trị cụ thể của this 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.

+ +

Example 1

+ +
// 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'
+
+ +

Example 2

+ +
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
+
+ +

 Chú ý trong chế độ  non–strict mode, với call và apply, nếu giá trị được truyền vào this 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 ToObject. Vì thế nếu bạn truyền vào giá trị primitive như 7 hoặc 'foo', nó sẽ được chuyển đổi thành Object bằng cách sử dụng các constructor liên quan, do đó 7 sẽ được chuyển đổi thành đối tượng như tạo bằng new Number(7) và string 'foo' cũng được chuyển đổi thành đối tượng như tạo bằng new String('foo'), ví dụ:

+ +
function bar() {
+  console.log(Object.prototype.toString.call(this));
+}
+
+bar.call(7);     // [object Number]
+bar.call('foo'); // [object String]
+
+ +

The bind method

+ +

ECMAScript 5 giới thiệu {{jsxref("Function.prototype.bind()")}}. Gọi f.bind(someObject) tạo ra một hàm mới với cùng thân hàm và phạm vi như hàm f, nhưng this 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 bind, bất kể các hàm được sử dụng thế nào..

+ +
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
+
+ +

Arrow functions

+ +

Trong arrow functions, this giữ giá trị ?this 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.

+ +
var globalObject = this;
+var foo = (() => this);
+console.log(foo() === globalObject); // true
+ +
+

 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.

+
+ +
// 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
+ +

Không có vấn đề gì ở đây, this của foo 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: this của chúng giữ giá trị this của lexical context kèm theo.

+ +
// 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
+
+ +

Trong ví dụ trên, hàm (gọi nó là hàm ẩn danh A) gán cho obj.bar 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à, this của hàm B được thiết lập vĩnh viễn là this của obj.bar (hàm A) khi được gọi. Khi hàm trả về (hàm B)  được gọi, this của nó sẽ luôn là  những gì được thiết lập ban đầu. Trong đoạn mã trên, this của hàm B được thiết lập theo this của hàm A đó là obj, vì thế nó vẫn được thiết lập là obj ngay cả khi được gọi  theo cách thông thường thiết lập this thành undefined 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).

+ +

As an object method

+ +

Khi một hàm được gọi như là một phương thức của đối tượng,this được đặt thành đối tượng mà có phương thức được gọi trên.

+ +

Trong ví dụ dưới đây, khi o.f() được gọi, this bên trong hàm sẽ liên kết với đối tượng o.

+ +
var o = {
+  prop: 37,
+  f: function() {
+    return this.prop;
+  }
+};
+
+console.log(o.f()); // 37
+
+ +

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 f bên trong đối tượng o. 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 o.f. Làm như vậy sẽ có kết quả tương tự:

+ +
var o = {prop: 37};
+
+function independent() {
+  return this.prop;
+}
+
+o.f = independent;
+
+console.log(o.f()); // 37
+
+ +

Điều này chứng tỏ rằng vấn đề chỉ là việc gọi hàm f của o.

+ +

Tương tự, ràng buộc với this 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 g của đối tượng o.b. Khi thực thi, this bên trong hàm sẽ tham chiếu tới o.b. Thực tế đối tượng này là một thành viên của o không ảnh hưởng; tham chiếu trực tiếp nhất mới là quan trọng nhất.

+ +
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
+
+ +

this on the object's prototype chain

+ +

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, this refers to the object the method was called on, as if the method were on the object.

+ +
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
+
+ +

In this example, the object assigned to the variable p doesn't have its own f property, it inherits it from its prototype. But it doesn't matter that the lookup for f eventually finds a member with that name on o; the lookup began as a reference to p.f, so this inside the function takes the value of the object referred to as p. That is, since f is called as a method of p, its this refers to p. This is an interesting feature of JavaScript's prototype inheritance.

+ +

this with a getter or setter

+ +

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 this bound to the object from which the property is being set or gotten.

+ +
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
+
+ +

As a constructor

+ +

When a function is used as a constructor (with the {{jsxref("Operators/new", "new")}} keyword), its this is bound to the new object being constructed.

+ +
+

While the default for a constructor is to return the object referenced by this, it can instead return some other object (if the return value isn't an object, then the this object is returned).

+
+ +
/*
+ * 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
+
+ +

In the last example (C2), because an object was returned during construction, the new object that this was bound to simply gets discarded. (This essentially makes the statement "this.a = 37;" dead code. It's not exactly dead because it gets executed, but it can be eliminated with no outside effects.)

+ +

As a DOM event handler

+ +

When a function is used as an event handler, its this 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 addEventListener()).

+ +
// 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);
+}
+ +

In an inline event handler

+ +

When the code is called from an inline on-event handler, its this is set to the DOM element on which the listener is placed:

+ +
<button onclick="alert(this.tagName.toLowerCase());">
+  Show this
+</button>
+
+ +

The above alert shows button. Note however that only the outer code has its this set this way:

+ +
<button onclick="alert((function() { return this; })());">
+  Show inner this
+</button>
+
+ +

In this case, the inner function's this isn't set so it returns the global/window object (i.e. the default object in non–strict mode where this isn't set by the call).

+ +

Specifications

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-this-keyword', 'The this keyword')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.this")}}

+ +

See also

+ + 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 +--- +
{{jsSidebar("Operators")}}
+ +

Phương thức typeof trả về kiểu dữ liệu của đối tượng nào đó.

+ +
{{EmbedInteractiveExample("pages/js/expressions-typeof.html")}}
+ + + +

Cú pháp

+ +

Phương thức typeof được theo sau bởi toán hạng operand:

+ +
typeof operand
+typeof(operand)
+
+ +

Các tham số

+ +
+
operand
+
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.
+
+ +

Định nghĩa

+ +

Bảng tóm tắt bên dưới mô tả các giá trị có thể trả về của typeof. Xem thêm thông tin tại trang JavaScript data structure.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeResult
{{glossary("Undefined")}}"undefined"
{{glossary("Null")}}"object" (see {{anch("null", "below")}})
{{glossary("Boolean")}}"boolean"
{{glossary("Number")}}"number"
{{glossary("BigInt")}}"bigint"
{{glossary("String")}}"string"
{{glossary("Symbol")}} (new in ECMAScript 2015)"symbol"
Host object (provided by the JS environment)Implementation-dependent
{{glossary("Function")}} object (implements [[Call]] in ECMA-262 terms)"function"
Any other object"object"
+ +

Các ví dụ

+ +
// 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 Array.isArray 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';
+
+ +

Additional information

+ +

null

+ +
// This stands since the beginning of JavaScript
+typeof null === 'object';
+
+ +

In the first implementation of JavaScript, JavaScript values were represented as a type tag and a value. The type tag for objects was 0. null was represented as the NULL pointer (0x00 in most platforms). Consequently, null had 0 as type tag, hence the "object" typeof return value. (reference)

+ +

A fix was proposed for ECMAScript (via an opt-in), but was rejected. It would have resulted in typeof null === 'null'.

+ +

Using new operator

+ +
// 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'
+
+ +

Need for parentheses in Syntax

+ +
// Parentheses can be used for determining the data type of expressions.
+var iData = 99;
+
+typeof iData + ' Wisen'; // 'number Wisen'
+typeof (iData + ' Wisen'); // 'string'
+
+ +

Regular expressions

+ +

Callable regular expressions were a non-standard addition in some browsers.

+ +
typeof /s/ === 'function'; // Chrome 1-12 Non-conform to ECMAScript 5.1
+typeof /s/ === 'object';   // Firefox 5+  Conform to ECMAScript 5.1
+
+ +

Errors

+ +

Before ECMAScript 2015, typeof was always guaranteed to return a string for any operand it was supplied with. Even with undeclared identifiers, typeof will return 'undefined'. Using typeof could never generate an error.

+ +

But with the addition of block-scoped {{jsxref("Statements/let", "let")}} and {{jsxref("Statements/const")}} using typeof on let and const variables (or using typeof on a class) in a block before they are declared will throw a {{jsxref("ReferenceError")}}. Block scoped variables are in a "temporal dead zone" from the start of the block until the initialization is processed, during which, it will throw an error if accessed.

+ +
typeof undeclaredVariable === 'undefined';
+
+typeof newLetVariable; // ReferenceError
+typeof newConstVariable; // ReferenceError
+typeof newClass; // ReferenceError
+
+let newLetVariable;
+const newConstVariable = 'hello';
+class newClass{};
+ +

Exceptions

+ +

All current browsers expose a non-standard host object {{domxref("document.all")}} with type undefined.

+ +
typeof document.all === 'undefined';
+
+ +

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 document.all having type 'undefined' is classified in the web standards as a "willful violation" of the original ECMA JavaScript standard.

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-typeof-operator', 'The typeof Operator')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-typeof-operator', 'The typeof Operator')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-11.4.3', 'The typeof Operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES3', '#sec-11.4.3', 'The typeof Operator')}}{{Spec2('ES3')}}
{{SpecName('ES1', '#sec-11.4.3', 'The typeof Operator')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.typeof")}}

+ +

IE-specific notes

+ +

On IE 6, 7, and 8 a lot of host objects are objects and not functions. For example:

+ +
typeof alert === 'object'
+ +

See also

+ + -- cgit v1.2.3-54-g00ecf