Hello World

  • Thuộc tính typelanguage không bắt buộc.

  • Lợi ích của file riêng: trình duyệt tải và lưu vào cache. Trang khác dùng cùng script sẽ lấy từ cache thay vì tải lại, nên file chỉ tải một lần.

  • Nếu đặt src, phần nội dung script bị bỏ qua.

    <script src="file.js">
      alert(1); // the content is ignored, because src is set
    </script>

Semicolons

Trong đa số trường hợp, xuống dòng ngụ ý có dấu chấm phẩy; nhưng không phải luôn luôn!

Có trường hợp xuống dòng không đồng nghĩa với dấu chấm phẩy. Ví dụ:

alert(3 + 1 + 2)

Giờ thử bỏ dấu chấm phẩy sau alert:

alert("Hello")[(1, 2)].forEach(alert)

JavaScript không tự chèn dấu chấm phẩy trước [...]. Nên ví dụ cuối được coi là một statement duy nhất.

alert("Hello")[(1, 2)].forEach(alert)

Khuyến nghị luôn đặt dấu chấm phẩy giữa các statement, dù đã xuống dòng. Cộng đồng chấp nhận rộng rãi quy tắc này.

Strict Mode

JavaScript hiện đại hỗ trợ “classes” và “modules” và tự bật use strict (Strict Mode. Dùng chúng thì không cần thêm chỉ thị "use strict" thủ công.

Hiện tại, "use strict"; vẫn hữu ích ở đầu script. Sau này khi toàn bộ code dùng classes/modules thì có thể bỏ.

Data Types

Chúng ta có thể gán bất kỳ type nào vào biến; cùng biến có thể lúc là string, lúc là number:

// no error
let message = "hello"
message = 123456

Ngôn ngữ như JavaScript được gọi là “dynamically typed”: có data types nhưng biến không bị ràng buộc cố định.

Number

Ngoài số thông thường, còn có “special numeric values” thuộc type này: Infinity, -Infinity, NaN:

  • Infinity: represents the mathematical Infinity ∞. It is a special value that’s greater than any number.

  • NaN: represents a computational error. NaN is sticky. Any further mathematical operation on NaN returns NaN:

    alert(NaN + 1) // NaN
    alert(3 * NaN) // NaN
    alert("not a number" / 2 - 1) // NaN

Vì vậy nếu có NaN trong biểu thức, nó lan ra cả kết quả (ngoại lệ: NaN ** 01).

BigInt

Type number không biểu diễn an toàn số nguyên > (2^53-1) (9007199254740991) hoặc < -(2^53-1).

Chính xác hơn, number có thể lưu số lớn hơn (tới 1.7976931348623157 * 10^308), nhưng ngoài khoảng ±(2^53-1) sẽ mất chính xác do giới hạn 64-bit, chỉ lưu giá trị xấp xỉ.

Ví dụ hai số ngay trên ngưỡng an toàn này lại bằng nhau:

console.log(9007199254740991 + 1) // 9007199254740992
console.log(9007199254740991 + 2) // 9007199254740992

BigInt được thêm để biểu diễn số nguyên tùy ý độ dài.

Tạo BigInt bằng cách thêm n sau số nguyên:

// the "n" at the end means it's a BigInt
const bigInt = 1234567890123456789012345678901234567890n

Null and Undefined

Thường dùng null cho giá trị “rỗng/không biết”; undefined là giá trị khởi tạo mặc định khi chưa gán.

Objects and Symbols

Các type còn lại gọi là “primitive” vì chỉ chứa một giá trị. Ngược lại, objects lưu tập dữ liệu và thực thể phức tạp.

Typeof

typeof null trả "object" — đây là lỗi lịch sử của typeof, giữ vì compatibility.

Functions thuộc object type nhưng typeof trả về "function".

Summary

typeof(x) giống typeof x. typeof là operator, không phải function; ngoặc dùng cho nhóm biểu thức toán học.

Alert, Prompt and Confirm

Tất cả đều là modal: tạm dừng thực thi và chặn tương tác đến khi đóng hộp thoại.

Type Conversion

Numeric Conversion – Xảy ra trong phép toán; có thể dùng Number(value).

Quy tắc chuyển đổi:

ValueBecomes…
undefinedNaN
null0
true and false1 and 0
stringWhitespaces (includes spaces, tabs \t, newlines \n etc.) from the start and end are removed. If the remaining string is empty, the result is 0. Otherwise, the number is “read” from the string. An error gives NaN.

Ví dụ:

alert(Number("   123   ")) // 123
alert(Number("123z")) // NaN (error reading a number at "z")
alert(Number(true)) // 1
alert(Number(false)) // 0

Boolean Conversion – Trong phép logic; dùng Boolean(value).

Quy tắc:

ValueBecomes…
0, null, undefined, NaN, ""false
any other valuetrue

Khi đổi string sang number, khoảng trắng đầu/cuối bị trim. Chuỗi toàn khoảng trắng như \t, \n, space thường sẽ thành 0.

Ví dụ:

" \t \n" - 2 = -2 // (7)

Ngoài ra, so sánh == định nghĩa undefinednull chỉ bằng nhau với nhau, không bằng thứ khác. Vì vậy (2) null == 0 là false:

alert(null > 0) // (1) false
alert(null == 0) // (2) false
alert(null >= 0) // (3) true

Operators

Unary operators có precedence cao hơn binary tương ứng.

Ví dụ:

// both values converted to numbers before the binary plus
alert(+apples + +oranges) // 5

Increment/decrement

Dạng prefix trả giá trị mới; postfix trả giá trị cũ (trước khi tăng/giảm).

Ví dụ phân biệt:

let counter = 1
let a = ++counter // (*)
 
alert(a) // 2

Giờ dùng postfix:

let counter = 1
let a = counter++ // (*) changed ++counter to counter++
 
alert(a) // 1

Tóm lại:

Nếu không dùng kết quả, dùng dạng nào cũng như nhau:

let counter = 0
counter++
++counter
alert(counter) // 2, the lines above did the same

Muốn dùng ngay kết quả thì dùng prefix:

let counter = 0
alert(++counter) // 1

Muốn tăng nhưng dùng giá trị cũ thì dùng postfix:

let counter = 0
alert(counter++) // 0

Toán tử ++/-- cũng dùng trong expression; precedence cao hơn hầu hết phép toán số học khác.

OR and AND

Precedence của AND && cao hơn OR ||.

Nói cách khác, && được tính trước ||.

Do đó a && b || c && d tương đương (a && b) || (c && d).

Nullish

Khác biệt chính giữa ||??:

  • || trả giá trị đầu tiên truthy.
  • ?? trả giá trị đầu tiên defined.

Ví dụ:

let height = 0
 
alert(height || 100) // 100
alert(height ?? 100) // 0

Precedence của ?? bằng ||: được tính trước =?, sau +, *.

Resources