NỘI DUNG BÀI HỌC

✅Biến là gì?
✅Công dụng của Biến trong ngôn ngữ lập trình Javascript
✅Cách khai báo biến, các quy tắc đặt tên biến
✅Kiểu dữ liệu trong Javascript
✅Các phương thức thường dùng cho String và Number
✅Các phép toán số học và ép kiểu
✅Tìm hiểu sâu về các loại toán tử

✅Phần 1: BIẾN - NHỮNG CHIẾC HỘP GHI NHỚ THÔNG TIN

✳️Biến là cái gì?

Nói một cách dễ hiểu nhất, biến giống như một chiếc hộp có dán nhãn dùng để chứa thông tin.

Mỗi chiếc hộp (mỗi biến) luôn có hai thứ:

  • Cái nhãn (Tên biến): Để chúng ta có thể gọi tên và tìm lại đúng chiếc hộp mình cần.
  • Thứ bên trong (Giá trị của biến): Là thông tin mà chúng ta cất vào trong hộp (ví dụ: một con số, một dòng chữ, ...).

Mục đích của biến là để lưu trữ dữ liệu và chúng ta có thể lấy ra dùng lại bất cứ khi nào cần bằng cách gọi tên của nó.

✳️Biến và Bộ nhớ máy tính hoạt động ra sao?

Đây là phần cực kỳ thú vị! Khi bạn tạo ra một biến, có một câu chuyện đang diễn ra "phía sau hậu trường" bên trong bộ nhớ máy tính (RAM).

Hãy tưởng tượng bộ nhớ máy tính là một cái tủ đựng đồ khổng lồ với hàng triệu ô tủ nhỏ, và JavaScript là người quản lý cái tủ này.


Câu chuyện diễn ra theo 3 bước:


Bước 1: Khai báo (Declaration)

Bạn nói với JavaScript: let tuoi;

  • Bạn nói: "Này anh quản lý JavaScript, tôi cần một cái hộp để đựng 'tuổi'. Tìm cho tôi một ô tủ trống và dán cái nhãn tuoi lên đó nhé."

  • JavaScript làm: Nó sẽ tìm một ô nhớ còn trống trong "cái tủ khổng lồ", và dán cái nhãn tuoi lên đó. Tại thời điểm này, chiếc hộp đã có tên nhưng bên trong hoàn toàn trống rỗng. Trạng thái này trong lập trình gọi là undefined (chưa xác định).


Bước 2: Gán giá trị (Assignment)

Sau đó, bạn nói: tuoi = 30;

  • Bạn nói: "Anh quản lý, hãy cất số 30 vào trong cái hộp có nhãn tuoi giúp tôi."

  • JavaScript làm: Nó tìm đến đúng cái hộp có nhãn tuoi và bỏ giá trị 30 vào bên trong.


Bước 3: Truy xuất (Retrieval)

Khi bạn cần dùng, bạn chỉ cần gọi: console.log(tuoi);

  • Bạn nói: "Anh quản lý ơi, xem giúp trong hộp tuoi đang chứa cái gì thế?"

  • JavaScript làm: Nó chạy tới cái hộp tuoi, mở ra xem và báo lại cho bạn: "À, trong đó có số 30!".

Hiểu được câu chuyện này, bạn đã hiểu được bản chất của việc khai báo và sử dụng biến rồi đó!

Cách khai báo biến trong JavaScript

Trong JavaScript hiện đại, chúng ta có 2 "từ khóa" chính để tạo ra một biến. Chúng tương ứng với 2 loại hộp khác nhau:

1. Dùng let (Hộp có thể thay đổi đồ bên trong)

Từ khóa let dùng để tạo ra một biến mà giá trị của nó có thể được thay đổi sau này.

// Bước 1: Khai báo một chiếc hộp tên là `diemSo`
let diemSo;

// Bước 2: Cất số 8 vào hộp
diemSo = 8;

// Bước 3: Kiểm tra, kết quả là 8
console.log(diemSo);

// Sau đó, chúng ta có thể thay đổi giá trị bên trong
diemSo = 10;

// Kiểm tra lại, kết quả bây giờ là 10
console.log(diemSo);

let là cách khai báo biến phổ biến và linh hoạt nhất.

2. Dùng const (Hộp đã cất đồ vào là khóa lại luôn!)

const (viết tắt của constant - hằng số) dùng để tạo ra một biến mà giá trị của nó KHÔNG THỂ thay đổi sau lần gán đầu tiên.
Nó dùng để lưu những giá trị mà chúng ta biết chắc sẽ không bao giờ thay đổi, ví dụ như số PI (3.14), ngày sinh, hoặc mã số thuế.

// Khai báo hằng số PI và gán giá trị luôn
const soPI = 3.14;

// Kiểm tra, kết quả là 3.14
console.log(soPI);

// Nếu cố tình thay đổi giá trị...
soPI = 3.14159; // Dòng này sẽ báo LỖI ngay lập tức!


Khi nào dùng let, khi nào dùng const?

Quy tắc đơn giản: Cứ dùng const trước. Nếu bạn nhận ra giá trị của biến đó cần phải thay đổi, hãy sửa lại thành let.

✳️NGHỆ THUẬT "IN" BIẾN RA MÀN HÌNH

Công cụ chính chúng ta sử dụng để hiển thị thông tin trong quá trình phát triển là console.log(). Nó sẽ in dữ liệu ra tab Console trên trình duyệt. Nhưng việc kết hợp văn bản và biến sao cho hiệu quả lại có nhiều cách khác nhau.

1. Cách cổ điển: Nối chuỗi bằng dấu + (String Concatenation)

Đây là cách làm cơ bản nhất, tồn tại từ những ngày đầu của JavaScript. Bạn dùng toán tử + để "dán" các chuỗi và các biến lại với nhau.

  • Tưởng tượng: Nó giống như bạn đang cắt dán giấy thủ công, bạn lấy từng mẩu giấy (chuỗi, biến) và dùng hồ dán (+) để dán chúng lại thành một câu hoàn chỉnh.

  • Ví dụ:

const tenTestCase = "TC01 - Login with valid credentials";
const trangThai = "Passed";
const thoiGianChay = 3500; // miligiây

console.log(
  "Test case: " + tenTestCase + " - Status: " + trangThai + " - Duration: " + thoiGianChay + "ms"
);
  • Ưu điểm:

    • Hoạt động trên mọi phiên bản JavaScript, mọi trình duyệt.

  • Nhược điểm:

    • Rất cồng kềnh và khó đọc khi có nhiều biến.

    • Dễ gây lỗi: Thường xuyên quên dấu cách ở đầu hoặc cuối chuỗi, làm các từ bị dính vào nhau (ví dụ: Status:Passed).

2. Cách tiện lợi: Dùng dấu phẩy , trong console.log

Bản thân hàm console.log có thể nhận nhiều tham số, cách nhau bởi dấu phẩy. Nó sẽ tự động in các giá trị ra và thêm một dấu cách giữa chúng.

  • Tưởng tượng: Bạn đưa cho hàm console.log một rổ nguyên liệu (các biến, chuỗi), và nó sẽ tự động bày biện chúng ra đĩa cho bạn.

  • Ví dụ:

const tenTestCase = "TC02 - Login with invalid password";
const trangThai = "Failed";

console.log("Test case:", tenTestCase, "- Status:", trangThai);
// Kết quả: Test case: TC02 - Login with invalid password - Status: Failed
  • Ưu điểm:

    • Nhanh và sạch sẽ hơn dùng dấu +.

    • Tự động thêm dấu cách, không lo lỗi dính chữ.

    • Rất tốt để xem nhanh giá trị của nhiều biến cùng lúc, đặc biệt là các object.

  • Nhược điểm:

    • Chỉ hoạt động với console.log, bạn không thể dùng cách này để tạo ra một biến chuỗi mới.

    • Kiểm soát định dạng (format) không linh hoạt bằng cách khác.


3. Cách "xịn" nhất: Template Literals (Dấu backtick `)

Đây là cách làm hiện đại, mạnh mẽ và được khuyên dùng nhất trong hầu hết các trường hợp. Bạn sử dụng cặp dấu backtick (`) để bọc toàn bộ chuỗi và dùng cú pháp ${ten_bien} để nhúng biến trực tiếp vào.

  • Tưởng tượng: Nó giống như một mẫu đơn có sẵn chỗ trống. Bạn chỉ cần điền thông tin (biến) vào đúng chỗ trống đó. Cực kỳ tự nhiên và trực quan.

  • Ví dụ:

const tenTestCase = "TC03 - Add product to cart";
const trangThai = "Passed";
const soLuongSanPham = 5;

const thongBao = `Test case: ${tenTestCase} - Status: ${trangThai} - Products added: ${soLuongSanPham}`;
console.log(thongBao);
  • Ưu điểm:

    • Cực kỳ dễ đọc và dễ viết, kể cả với những chuỗi phức tạp.

    • Cho phép viết chuỗi trên nhiều dòng.

    • Có thể nhúng cả những biểu thức tính toán phức tạp bên trong: ${soLuongSanPham * 2}.

  • Nhược điểm:

    • Gần như không có trong bối cảnh xuất dữ liệu. Đây là tiêu chuẩn hiện đại.

Tổng kết và Lời khuyên

Cách làm

Ví dụ

Khi nào dùng?

Nối chuỗi +

"Tên: " + ten

Nên tránh. Chỉ dùng khi bắt buộc phải làm việc trên môi trường rất cũ.

Dấu phẩy ,

console.log("Tên:", ten)

Tốt để xem nhanh, gỡ lỗi nhiều biến cùng lúc.

Template Literals `

`Tên: ${ten}`

Tiêu chuẩn hiện đại. Dùng trong hầu hết mọi trường hợp.

Lời khuyên cuối cùng: Hãy tập thói quen sử dụng Template Literals (dấu `) làm cách chính. Nó sẽ giúp code của bạn sạch sẽ, dễ đọc và ít lỗi hơn. 

Cách viết gọn hơn: Vừa khai báo, vừa gán giá trị

Hãy quay lại với câu chuyện "anh quản lý tủ đồ":

  • Cách viết dài (2 bước):

    1. let diemSo;  "Anh quản lý, giữ cho tôi một ô tủ tên là diemSo nhé."

    2. diemSo = 8;  "Giờ thì cất số 8 vào cái tủ diemSo đó giúp tôi."

  • Cách viết gọn (1 bước):
    let diemSo = 8; "Anh quản lý, tìm cho tôi một ô tủ trống, dán nhãn diemSo lên và cất ngay số 8 vào đó giúp tôi. Làm một lèo luôn nhé!"


Như bạn thấy, cách viết này ngắn gọn và hiệu quả hơn rất nhiều. Bạn ra lệnh cho JavaScript thực hiện cả hai việc cùng một lúc: vừa tạo ra chiếc hộp, vừa bỏ đồ vào ngay lập tức.

Đối với const, việc này là bắt buộc. Vì const là hằng số (chiếc hộp bị khóa lại), bạn phải bỏ đồ vào ngay lúc tạo ra nó chứ không thể để hộp rỗng rồi mới cất đồ vào sau được.

// ĐÚNG, vừa tạo vừa gán giá trị
const tenWebsite = "Google";

// SAI, sẽ báo lỗi ngay lập tức!
const tenWebsite;
tenWebsite = "Google"; // Lỗi: Missing initializer in const declaration


Tóm lại: Dòng lệnh let diemSo = 8; là cách làm chuẩn và hiệu quả để tạo ra một biến tên là diemSo và gán cho nó giá trị ban đầu là 8.


✳️Quy tắc đặt tên biến trong JavaScript

Đặt tên biến không chỉ là để máy tính hiểu, mà quan trọng hơn là để con người (bạn và đồng nghiệp) đọc và hiểu được. Một cái tên tốt giống như một tấm biển chỉ đường rõ ràng. Dưới đây là những quy tắc bạn cần tuân thủ.

1. Quy tắc về ký tự

Tên biến chỉ được chứa:

  • Chữ cái: a-z, A-Z

  • Chữ số: 0-9

  • Dấu gạch dưới: _

  • Ký hiệu đô la: $

Quan trọng: Tên biến không được bắt đầu bằng một con số.

 Hợp lệ: tenNguoiDung, user_age, $price, price1

Không hợp lệ: 1price (bắt đầu bằng số), user-name (chứa gạch ngang), tên người dùng (chứa khoảng trắng)

2. Quy tắc "Viết liền, không dấu" và Chuẩn mực camelCase

Tên biến phải là một từ duy nhất, không chứa khoảng trắng. Để nối các từ lại với nhau, chuẩn mực chung của cộng đồng JavaScript là dùng camelCase (viết kiểu lạc đà).

camelCase nghĩa là:

  • Viết thường chữ cái đầu tiên của từ thứ nhất.

  • Viết hoa chữ cái đầu tiên của các từ tiếp theo.

Tên này được gọi là "lạc đà" vì các chữ cái viết hoa ở giữa trông giống như những cái bướu của con lạc đà.

 Nên dùng: tenKhachHang, soDienThoai, tongSoTienPhaiTra

Không nên: tenkhachhang (khó đọc), ten_khach_hang (kiểu "rắn bò" - snake_case, thường dùng trong ngôn ngữ khác như Python), TenKhachHang (kiểu PascalCase, thường dùng cho Class)

3. Không được dùng "Từ khóa" (Reserved Words)

JavaScript có một danh sách các từ dành riêng để sử dụng cho các cú pháp lệnh của nó. Bạn không thể dùng những từ này để đặt tên cho biến.

Hãy tưởng tượng bạn không thể đặt tên con là "Động từ" hay "Tính từ" được.

Một vài ví dụ về từ khóa:

  • let, const, var

  • if, else, switch

  • for, while

  • function, return, class

 Sai bét: let let = 10; // Lỗi cú pháp

4. Tên biến có phân biệt chữ HOA - chữ thường

JavaScript coi chữ hoa và chữ thường là hoàn toàn khác nhau. Điều này có nghĩa là:

let ten = "An";

let Ten = "Bình";

let TEN = "Cường";

Đây là ba biến hoàn toàn khác nhau, chứa ba giá trị khác nhau. Vì vậy, hãy cẩn thận và nhất quán trong cách đặt tên của bạn.

5. Quy tắc quan trọng nhất: Đặt tên phải có Ý NGHĨA!

Đây không phải là quy tắc về cú pháp, nhưng lại là quy tắc quan trọng nhất để trở thành một lập trình viên giỏi. Tên biến phải mô tả rõ ràng dữ liệu mà nó chứa.

Hãy tự hỏi: "Sau 6 tháng nữa nhìn lại, mình có hiểu biến này dùng để làm gì không?"

let x = 10;
let y = "Trung";
let z = x * 2;

x, y, z là gì? Chẳng ai hiểu nổi.

let soLuong = 10;
let tenNguoiDung = "Trung";
let diemThuong = soLuong * 2;

Rõ ràng, dễ hiểu ngay lập tức.


Ký hiệu đô la ($) là một trong những ký tự hợp lệ khi đặt tên biến trong JavaScript, và nó có một lịch sử khá thú vị.

Nói một cách đơn giản: Về mặt cú pháp, JavaScript coi ký hiệu $ giống hệt như một chữ cái thông thường. Bạn có thể dùng nó để bắt đầu hoặc đặt ở bất kỳ đâu trong tên biến.

let $ten = "An"; // Hợp lệ

let luong$ = 5000; // Hợp lệ

Lời khuyên

  • Về mặt kỹ thuật, bạn có thể dùng $ trong bất kỳ tên biến nào.

  • Tránh dùng $ cho các biến thông thường (như let $tuoi = 20;) vì nó có thể gây nhầm lẫn cho người khác khi đọc code của bạn.

✅Phần 2: KIỂU DỮ LIỆU - NHỮNG LOẠI "ĐỒ VẬT" BÊN TRONG BIẾN

Bây giờ, hãy cùng khám phá xem bên trong những chiếc hộp đó có thể chứa những loại "đồ vật" (dữ liệu) nào. Việc này cực kỳ quan trọng, vì trong automation testing, bạn sẽ phải làm việc với đủ loại dữ liệu: từ các đoạn text để điền vào form, các con số để kiểm tra giá tiền, cho đến những cấu trúc phức tạp hơn để quản lý tài khoản người dùng.


Trong JavaScript, có các  nhóm dữ liệu chính như sau:

Dữ liệu nguyên thủy (Primitive Types)

1. String (Chuỗi)

Định nghĩa chung: Đây là kiểu dữ liệu đơn giản và phổ biến nhất, dùng để biểu thị các đoạn văn bản. Một chuỗi có thể là một ký tự, một từ, một câu, hay cả một cuốn sách. Để tạo một chuỗi, bạn chỉ cần đặt nội dung văn bản bên trong cặp dấu nháy đơn (' '), nháy kép (" ") hoặc backtick (`).

let loiChao = 'Xin chào buổi sáng';
const tenSach = "Lập trình JavaScript cơ bản";

Dấu backtick (`) rất lợi hại vì nó cho phép bạn nhúng biến vào chuỗi một cách dễ dàng, hay còn gọi là Template Literals.

const tenNguoiHoc = "An";
const loiGioiThieu = `Tên tôi là ${tenNguoiHoc}.`; // Kết quả: Tên tôi là An

Ứng dụng trong Automation: Trong automation, chuỗi là thứ bạn dùng liên tục: tên đăng nhập, mật khẩu, các đoạn văn bản để tìm kiếm, hay các thông báo lỗi cần kiểm tra.

const username = "automation.tester@gmail.com";
const expectedErrorMessage = "Sai mật khẩu, vui lòng thử lại.";

// Dùng backtick để tạo selector động trong Playwright
const productName = "iPhone 15 Pro Max";
const productSelector = `h2:has-text("${productName}")`;​

2. Number (Số)

Định nghĩa chung: Đúng như tên gọi, kiểu này dùng để biểu thị các con số. Một điểm đặc biệt của JavaScript là nó không phân biệt số nguyên (ví dụ: 10) và số thập phân (ví dụ: 3.14), tất cả đều là kiểu number. Bạn có thể thực hiện mọi phép toán với nó

let tuoi = 30;
const PI = 3.14;
let ketQua = (tuoi - 5) * 2; // (30 - 5) * 2 = 50

Ứng dụng trong Automation: Khi viết kịch bản test, bạn sẽ dùng number để chỉ số lượng sản phẩm cần thêm vào giỏ, kiểm tra giá tiền có chính xác không, hoặc đặt thời gian chờ (timeout) cho một hành động.

const soLuongCanThem = 3;
const giaTienMongDoi = 150.75; // 150.75 USD
const thoiGianChoToiDa = 5000; // 5000 mili giây (5 giây)


3. Boolean (Luận lý đúng sai)

Định nghĩa chung: Kiểu dữ liệu này cực kỳ đơn giản nhưng vô cùng quyền lực. Nó chỉ có thể nhận một trong hai giá trị: true (đúng) hoặc false (sai). Hãy tưởng tượng nó như một cái công tắc đèn: chỉ có thể bật (true) hoặc tắt (false). Máy tính dùng kiểu dữ liệu này để đưa ra quyết định.

let denDangBat = true;
let daTotNghiep = false;
let duTuoiBauCu = 19 > 18; // Phép so sánh này trả về true


Ứng dụng trong Automation: Boolean là trái tim của việc kiểm tra và xác thực (assertion). Hầu hết các lệnh kiểm tra của bạn sẽ trả về true (nếu pass) hoặc false (nếu fail). Nó cũng dùng để điều khiển luồng kịch bản.

// Giả lập kết quả từ lệnh isVisible() của Playwright
let nutThanhToanIsVisible = true;

// Kịch bản test sẽ dựa vào biến này để quyết định
if (nutThanhToanIsVisible) {
  console.log("TEST PASS: Nút 'Thanh toán' đang hiển thị.");
  // ...tiếp tục click vào nút...
} else {
  console.log("TEST FAIL: Không tìm thấy nút 'Thanh toán'!");
}

 

4. undefined (Chưa được định nghĩa)

Định nghĩa chung: Một biến sẽ có giá trị này khi nó đã được khai báo nhưng chưa hề được gán một giá trị nào. Đây là trạng thái "hộp rỗng" mặc định do chính JavaScript tự động gán vào.

let diaChiNha;
console.log(diaChiNha); // undefined

Ứng dụng trong Automation: Điều này có thể xảy ra khi bạn cố gắng lấy một thuộc tính không tồn tại từ một đối tượng, hoặc một element bạn tìm kiếm không trả về kết quả như mong đợi.


5. null (Rỗng)

Định nghĩa chung: null cũng có nghĩa là "không có giá trị", nhưng nó khác với undefined ở chỗ nó được gán một cách có chủ đích bởi lập trình viên. Nó biểu thị sự vắng mặt của một giá trị mà bạn đã lường trước.

let xeHoi = null; // Tôi chủ động nói rằng không có xe hơi

 

Ứng dụng trong Automation: Bạn có thể dùng null để khởi tạo một biến sẽ chứa một element. Nếu sau bước tìm kiếm không thấy, biến đó vẫn là null, giúp bạn dễ dàng kiểm tra và dừng kịch bản nếu cần.

let popupKhuyenMai = null;
// ...chạy code tìm popup...
// Giả sử không tìm thấy
if (popupKhuyenMai === null) {
  console.log("INFO: Không có popup khuyến mãi nào xuất hiện. Bỏ qua bước đóng popup.");
}

Bảng so sánh nhanh

Tiêu chí

undefined

null

Ý nghĩa

Một biến đã được khai báo nhưng chưa bao giờ được gán giá trị.

Một biến được chủ động gán giá trị "rỗng".

Ai gán?

JavaScript tự động gán.

Lập trình viên chủ động gán.

Loại ví von

Hộp quà trống vì quên/chưa bỏ quà.

Hộp quà chứa tấm thiệp "không có quà".

Kiểu dữ liệu

typeof trả về undefined.

typeof trả về object (một lỗi lịch sử của JS).


Tình huống trong Automation

Hiểu rõ sự khác biệt này giúp bạn gỡ lỗi (debug) hiệu quả hơn.

  • Bạn gặp undefined khi:

    • Bạn cố gắng truy cập một thuộc tính không tồn tại trong một object. Ví dụ, object user chỉ có email và password, nhưng bạn lại gọi user.age.

    • Bạn quên gán giá trị cho một biến cấu hình.

    • Nó thường chỉ ra một lỗi logic hoặc lỗi đánh máy trong code của bạn.

  • Bạn gặp null khi:

    • Một hàm tìm kiếm element trên trang (ví dụ: document.querySelector(...)) không tìm thấy element nào khớp và trả về null.

    • Dữ liệu từ API trả về null cho một trường không bắt buộc mà người dùng không điền (ví dụ: diaChiPhu: null).

    • Nó thường biểu thị một trạng thái hợp lệ của chương trình (ví dụ: "không tìm thấy" hoặc "không có dữ liệu").

Kết luận: Khi bạn thấy undefined, hãy tự hỏi "Tại sao biến này chưa có giá trị?". Khi bạn thấy null, hãy hiểu rằng "Biến này đã được chủ động thiết lập là không có giá trị".

JavaScript trả về undefined bất cứ khi nào bạn yêu cầu một giá trị mà nó không thể tìm thấy.


✅Phần 3: BỘ ĐỒ NGHỀ "SƠ CHẾ" DỮ LIỆU: CÁC PHƯƠNG THỨC STRING & NUMBER

Ở các bài trước, chúng ta đã biết về các loại dữ liệu. Nhưng trong thực tế, dữ liệu bạn nhận được, đặc biệt là từ các trang web, thường không "sạch sẽ". Nó có thể bị dính khoảng trắng thừa, viết hoa/viết thường không nhất quán, hoặc lẫn lộn giữa chữ và số.

Trước khi có thể tính toán hay so sánh, chúng ta cần phải "sơ chế" và "làm sạch" dữ liệu đó. Bài học hôm nay sẽ trang bị cho bạn bộ đồ nghề thiết yếu để xử lý hai loại dữ liệu phổ biến nhất: String (Chuỗi) và Number (Số).


Các phương thức xử lý Chuỗi (String Methods)

Đây là những công cụ giúp bạn cắt, gọt, biến đổi và kiểm tra các chuỗi văn bản.

.length - Lấy độ dài của chuỗi

  • Công dụng: Trả về số lượng ký tự có trong chuỗi.

  • Ví dụ cơ bản:

    const loiChao = "Xin chào";
    console.log(loiChao.length); // 8
  • Ứng dụng trong Automation: Kiểm tra xem một đoạn văn bản có độ dài nằm trong giới hạn cho phép hay không (ví dụ: mật khẩu, tên sản phẩm).

    const matKhau = "12345";
    const laHopLe = matKhau.length >= 6;
    console.log(`Mật khẩu có hợp lệ không? ${laHopLe}`); // false


.toLowerCase() và .toUpperCase() - Đổi chữ hoa/thường

  • Công dụng: Chuyển toàn bộ chuỗi thành chữ thường hoặc chữ hoa.

  • Ví dụ cơ bản:

let ten = "Nguyễn Văn AN";
console.log(ten.toLowerCase()); // "nguyễn văn an"
console.log(ten.toUpperCase()); // "NGUYỄN VĂN AN"​

  • Ứng dụng trong Automation: Cực kỳ quan trọng khi bạn muốn so sánh text không phân biệt hoa/thường. Luôn chuyển cả hai chuỗi về cùng một dạng (thường là chữ thường) trước khi so sánh.

    const tenSanPhamThucTe = "IPHONE 15 PRO MAX"; // Lấy từ web
    const tenSanPhamMongDoi = "iphone 15 pro max";
    const khopTen = tenSanPhamThucTe.toLowerCase() === tenSanPhamMongDoi.toLowerCase();
    console.log(`Tên sản phẩm có khớp không? ${khopTen}`); // true

     

.trim() - Cắt bỏ khoảng trắng thừa

  • Công dụng: Loại bỏ các khoảng trắng (space, tab, newline) ở đầu và cuối chuỗi.

  • Ví dụ cơ bản:

    const emailInput = "   tester@gmail.com   ";
    console.log(`'${emailInput.trim()}'`); // "'tester@gmail.com'"
  • Ứng dụng trong Automation: Dữ liệu text lấy từ web thường bị dính khoảng trắng thừa. .trim() là bước làm sạch không thể thiếu trước khi bạn so sánh hay sử dụng dữ liệu đó.

const tenHienThi = "  Xin chào, Admin!  ";
const tenMongDoi = "Xin chào, Admin!";
console.log(`Tên hiển thị có đúng không? ${tenHienThi.trim() === tenMongDoi}`); // true​

.replace(giá_trị_cần_thay, giá_trị_mới) và .replaceAll()

  • Công dụng: Tìm kiếm và thay thế một đoạn văn bản bằng một đoạn văn bản khác. .replace() chỉ thay thế cái đầu tiên nó tìm thấy, .replaceAll() thay thế tất cả.

  • Ví dụ cơ bản:

let cau = "Mèo ăn cá, chó cũng ăn cá";
console.log(cau.replace("cá", "thịt")); // "Mèo ăn thịt, chó cũng ăn cá"
console.log(cau.replaceAll("cá", "thịt")); // "Mèo ăn thịt, chó cũng ăn thịt"​

  • Ứng dụng trong Automation: Công cụ quan trọng nhất để làm sạch dữ liệu số bị lẫn ký tự lạ.

    const giaTienText = "250.000 VNĐ";
    const giaTienClean = giaTienText.replaceAll(".", "").replace(" VNĐ", ""); // "250000"
    console.log(giaTienClean);


.includes(chuỗi_cần_tìm)

  • Công dụng: Kiểm tra xem một chuỗi có chứa một chuỗi con khác hay không. Trả về true hoặc false.

  • Ví dụ cơ bản:

const tieuDe = "Chào mừng đến với trang sản phẩm";
console.log(tieuDe.includes("sản phẩm")); // true​

Ứng dụng trong Automation: Một cách nhanh và dễ đọc để xác thực sự tồn tại của một từ khóa trong tiêu đề, URL, hoặc thông báo.

const thongBaoLoi = "Lỗi: Mật khẩu không đúng.";
const chuaTuKhoa = thongBaoLoi.includes("Mật khẩu");
console.log(`Thông báo lỗi có chứa từ khóa 'Mật khẩu' không? ${chuaTuKhoa}`); // true

.slice(vi_tri_bat_dau, vi_tri_ket_thuc) - Cắt lát chuỗi

  • Công dụng: Trích xuất một phần của chuỗi và trả về một chuỗi mới. Nó giống như bạn dùng dao cắt một lát bánh mì vậy.

    • vi_tri_ket_thuc là không bắt buộc. Nếu bỏ qua, nó sẽ cắt từ vi_tri_bat_dau đến hết chuỗi.

    • Bạn có thể dùng số âm để đếm ngược từ cuối chuỗi.

const chuoi = "Học JavaScript thật vui!";
console.log(chuoi.slice(4, 14)); // "JavaScript" (Bắt đầu từ vị trí 4, kết thúc trước vị trí 14)
console.log(chuoi.slice(15));    // "thật vui!" (Bắt đầu từ vị trí 15 đến hết)
console.log(chuoi.slice(-5));    // "vui!" (Lấy 5 ký tự cuối cùng)​

  • Ứng dụng trong Automation: Cực kỳ hữu ích khi bạn cần lấy một mã đơn hàng, một mã lỗi, hoặc một đoạn thông tin cụ thể từ một chuỗi dài và có cấu trúc cố định.

    const thongBao = "Đơn hàng #DH-12345 đã được tạo thành công.";
    // Lấy mã đơn hàng, bắt đầu từ vị trí 10 và dài 8 ký tự
    const maDonHang = thongBao.slice(10, 18);
    console.log(`Mã đơn hàng được trích xuất: ${maDonHang}`); // "DH-12345"

     

.split(ky_tu_phan_chia) - Tách chuỗi thành một Mảng

  • Công dụng: Đây là một trong những phương thức mạnh mẽ nhất. Nó "chặt" một chuỗi thành nhiều phần dựa trên một ký tự phân chia và trả về một mảng (Array) chứa các phần đó.

    • Lưu ý: Kết quả trả về là một Array, một kiểu dữ liệu chúng ta sẽ học kỹ ở bài sau, nhưng khái niệm của nó rất dễ hiểu: nó là một danh sách.

const danhSach = "táo,cam,xoài,nho";
const mangTraiCay = danhSach.split(",");
console.log(mangTraiCay); // ["táo", "cam", "xoài", "nho"]
console.log(mangTraiCay[0]); // "táo"

const hoTen = "Nguyễn Văn An";
const mangTen = hoTen.split(" ");
console.log(mangTen); // ["Nguyễn", "Văn", "An"]​

  • Ứng dụng trong Automation: Vô cùng cần thiết khi bạn cần xử lý dữ-liệu-dạng-danh-sách được hiển thị dưới dạng một chuỗi duy nhất trên trang web.

    // Lấy danh sách các tag sản phẩm từ web
    const tagsText = "Áo thun, Cotton, Mùa hè, Giảm giá";
    
    // Tách chuỗi thành một danh sách các tag để kiểm tra
    const tagsArray = tagsText.split(", ");
    
    console.log(`Số lượng tag: ${tagsArray.length}`); // 4
    // Kiểm tra xem tag "Mùa hè" có tồn tại không
    console.log(`Có tag "Mùa hè" không? ${tagsArray.includes("Mùa hè")}`); // true

     

Các phương thức xử lý Số (Number Methods)

.toFixed(số_chữ_số_thập_phân)

  • Công dụng: Định dạng một con số để nó luôn có một số lượng chữ số thập phân nhất định. Kết quả trả về là một chuỗi (string).

  • Ví dụ cơ bản:

    const soPI = 3.14159;
    console.log(soPI.toFixed(2)); // "3.14"
  • Ứng dụng trong Automation: Rất cần thiết khi bạn cần kiểm tra một con số có định dạng tiền tệ trên giao diện người dùng.

    const tongTienTinhToan = 65.47123; // Kết quả tính toán của bạn
    const tongTienHienThiTrenWeb = "$65.47"; // Text lấy từ web
    
    const tongTienDinhDang = `$${tongTienTinhToan.toFixed(2)}`;
    console.log(`Hai giá trị có khớp không? ${tongTienDinhDang === tongTienHienThiTrenWeb}`); // true

     

.toString() - Chuyển số thành chuỗi

  • Công dụng: Đây là phương thức "đối nghịch" với Number(), parseInt, và parseFloat. Nó biến một giá trị kiểu number trở lại thành kiểu string.

  • Ví dụ cơ bản:

const soLuong = 123;
const soLuongText = soLuong.toString();

console.log(typeof soLuong);        // "number"
console.log(typeof soLuongText);    // "string"
console.log(soLuongText);           // "123"​

  • Ứng dụng trong Automation:  Rất cần thiết khi bạn cần ghép một con số (kết quả tính toán) vào một chuỗi để tạo locator động hoặc để so sánh với một ID sản phẩm dạng text trên trang web.

// Giả sử bạn có ID cơ bản của sản phẩm
const baseProductID = 11234;

// Bạn cần tạo selector cho sản phẩm tiếp theo
const nextProductID_number = baseProductID + 1; // 11235 (dạng number)

// Để tạo selector, bạn phải chuyển nó thành string
const selector = `#product-${nextProductID_number.toString()}`;

console.log(`Selector của sản phẩm tiếp theo là: ${selector}`);
// Kết quả: Selector của sản phẩm tiếp theo là: #product-11235​

Number.isInteger(value) - Kiểm tra xem có phải là số nguyên không

  • Công dụng: Đây là một hàm tiện ích (không phải gọi từ một biến số mà gọi trực tiếp từ Number). Nó kiểm tra xem giá trị được cung cấp có phải là một số nguyên hay không và trả về true hoặc false. Nó đáng tin cậy hơn việc dùng % 1.

  • Ví dụ cơ bản:

    console.log(Number.isInteger(15));      // true
    console.log(Number.isInteger(15.5));    // false
    console.log(Number.isInteger("15"));    // false (vì nó là string)
  • Ứng dụng trong Automation: Hữu ích khi bạn cần xác thực rằng một giá trị phải là số nguyên, ví dụ như số lượng sản phẩm trong giỏ hàng (bạn không thể mua 2.5 cái áo).

    // Giả sử bạn lấy được số lượng và đã chuyển nó thành number
    const soLuongTrongGio = 2.5;
    
    const laSoLuongHopLe = Number.isInteger(soLuongTrongGio);
    
    console.log(`Số lượng trong giỏ hàng có hợp lệ không? ${laSoLuongHopLe}`); // false
    // Dựa vào kết quả này, bạn có thể báo cáo test case là FAILED.

     

Hộp đồ nghề toán học - Đối tượng Math

JavaScript cung cấp một "hộp đồ nghề" toán học có sẵn tên là Math. Đây là một đối tượng chứa rất nhiều hàm hữu ích để xử lý các con số.

Các phương thức làm tròn số

  • Math.round(x) - Làm tròn theo quy tắc chung (>= .5 lên, < .5 xuống).

console.log(Math.round(4.7)); // 5
console.log(Math.round(4.4)); // 4​

  • Math.floor(x) - Luôn làm tròn XUỐNG (floor - sàn nhà).

    console.log(Math.floor(4.999)); // 4
  • Math.ceil(x) - Luôn làm tròn LÊN (ceil - trần nhà).

    console.log(Math.ceil(4.001)); // 5
  • Ứng dụng trong Automation: Tính toán phân trang. Với 25 sản phẩm và 10 sản phẩm/trang:

    • Bạn có Math.floor(25 / 10) = 2 trang đầy đủ.

    • Bạn cần Math.ceil(25 / 10) = 3 trang để hiển thị tất cả.

  • Math.random() - Tạo số ngẫu nhiên
  • Công dụng: Trả về một số thập phân ngẫu nhiên từ 0 đến dưới 1. Để tạo số nguyên ngẫu nhiên từ min đến max, ta dùng công thức: Math.floor(Math.random() * (max - min + 1)) + min.

  • Ứng dụng trong Automation: Tạo dữ liệu test động.

// Tạo email ngẫu nhiên để test chức năng đăng ký
const soNgauNhien = Math.floor(Math.random() * 10000);
const email = `user${soNgauNhien}@test.com`;
console.log(`Email ngẫu nhiên được tạo: ${email}`);​

  • Math.max(...) và Math.min(...) - Tìm số lớn/nhỏ nhất
  • Công dụng: Nhận vào một danh sách các con số và trả về số lớn nhất hoặc nhỏ nhất.

    • Định nghĩa chung: Toán tử này chỉ so sánh giá trị của hai vế. Điều nguy hiểm là nó sẽ cố gắng tự động ép kiểu dữ liệu để chúng có thể so sánh được với nhau.
    • Ví dụ cơ bản:
      • Hậu tố (soLuong++): "Đưa tôi giá trị CŨ, rồi anh tự cập nhật sau"

        Ứng dụng trong Automation: Tìm sản phẩm có giá cao nhất/thấp nhất trong một loạt kết quả để xác thực.

        const gia1 = 150;
        const gia2 = 99;
        const gia3 = 210;
        const giaCaoNhat = Math.max(gia1, gia2, gia3);
        console.log(`Giá cao nhất là: ${giaCaoNhat}`); // 210

         

        Công thức: Math.floor(Math.random() * (max - min + 1)) + min

        Mục tiêu: Tạo ra một số nguyên ngẫu nhiên trong khoảng từ min đến max (bao gồm cả min và max).

        Ví dụ cụ thể: Chúng ta muốn tạo một số ngẫu nhiên từ 50 đến 55. Kết quả mong muốn có thể là 50, 51, 52, 53, 54, hoặc 55.


         

        ## Diễn giải từng bước

        Công thức này hoạt động theo 4 bước logic đơn giản:

        Bước 1: (max - min + 1) – Tìm "Độ rộng" của khoảng số

        Đầu tiên, chúng ta cần biết có bao nhiêu con số có thể xuất hiện trong khoảng chúng ta muốn.

        • max - min: Lấy 55 - 50 sẽ cho kết quả là 5.

        • Nhưng nếu đếm, ta có các số: 50, 51, 52, 53, 54, 55 -> có tất cả 6 con số.

        • Vì vậy, ta luôn phải + 1 để bao gồm cả số bắt đầu.

        ➡️ (55 - 50 + 1) = 6. Đây là "độ rộng" hay số lượng các kết quả có thể có.

         

        Bước 2: Math.random() * (độ rộng) – Tạo số thập phân ngẫu nhiên

         

        Bây giờ, chúng ta dùng Math.random() để tạo một con số ngẫu nhiên trong khoảng "độ rộng" mà chúng ta vừa tính.

        • Math.random() cho ra một số từ 0 đến < 1.

        • Nhân nó với 6: Math.random() * 6 sẽ cho ra một số thập phân trong khoảng từ 0 đến < 6 (ví dụ: 0.123, 3.987, 5.999...).

         

        Bước 3: Math.floor(...) – Lấy "số thứ tự" ngẫu nhiên

        Chúng ta dùng Math.floor() để "chặt" bỏ phần thập phân và lấy số nguyên.

        • Áp dụng Math.floor vào khoảng 0 đến < 6, chúng ta sẽ nhận được một trong 6 số nguyên sau: 0, 1, 2, 3, 4, 5.

        Bạn có thể coi con số này là một "số thứ tự" ngẫu nhiên trong danh sách 6 kết quả của chúng ta.

         

        Bước 4: + min – "Dịch chuyển" khoảng số về đúng vị trí

        Ở bước 3, chúng ta có một số ngẫu nhiên từ 0 đến 5, nhưng chúng ta lại muốn một số từ 50 đến 55. Bước cuối cùng là "dịch chuyển" toàn bộ khoảng số này lên bằng cách cộng với min.

        • Nếu "số thứ tự" ngẫu nhiên là 0 ➡️ 0 + 50 = 50

        • Nếu "số thứ tự" ngẫu nhiên là 1 ➡️ 1 + 50 = 51

        • Nếu "số thứ tự" ngẫu nhiên là 2 ➡️ 2 + 50 = 52

        • ...

        • Nếu "số thứ tự" ngẫu nhiên là 5 ➡️ 5 + 50 = 55

        Bằng cách này, chúng ta đã biến đổi khoảng [0, 1, 2, 3, 4, 5] thành đúng khoảng [50, 51, 52, 53, 54, 55] mà chúng ta mong muốn.


         

        ## Tóm tắt logic

         

        1. Tính độ rộng: Có bao nhiêu lựa chọn? (max - min + 1)

        2. Tạo số thứ tự: Lấy một số thứ tự ngẫu nhiên từ 0 đến (độ rộng - 1). (Math.floor(Math.random() * độ rộng))

        3. Dịch chuyển: Lấy số thứ tự đó cộng với số bắt đầu. (số thứ tự + min)

        Đây là công thức tiêu chuẩn và đáng tin cậy nhất để tạo số nguyên ngẫu nhiên trong một khoảng cho trước.


        ✅Phần 4: CÁC PHÉP TOÁN SỐ HỌC VÀ ÉP KIỂU

        Ở pần trước, chúng ta đã được trang bị "bộ đồ nghề" để làm sạch và chuẩn bị dữ liệu. Bây giờ, với dữ liệu đã sạch, chúng ta sẽ bắt đầu thực hiện các phép tính toán – một kỹ năng không thể thiếu để xác thực các con số trong kịch bản automation của bạn.

        Các phép toán số học cơ bản

        Đây là những công cụ nền tảng nhất để thực hiện các phép tính toán trong JavaScript.

        1. Phép Cộng (+)

        • Công dụng: Dùng để cộng hai số lại với nhau.
        • Lưu ý đặc biệt: Đây là toán tử "hai mặt". Nếu một trong hai giá trị là chuỗi (string), nó sẽ thực hiện phép nối chuỗi thay vì cộng số.
          Ví dụ cơ bản (cộng số):
          const soLuongKeo = 10;
          const soLuongBanh = 5;
          const tongSo = soLuongKeo + soLuongBanh;
          
          console.log(`Tổng số kẹo và bánh là: ${tongSo}`); // Kết quả: 15
          Ví dụ cơ bản (nối chuỗi):
          const ho = "Nguyễn";
          const ten = "An";
          const hoTen = ho + " " + ten;
          
          console.log(`Họ và tên đầy đủ: ${hoTen}`); // Kết quả: "Nguyễn An"​

        2. Phép Trừ (-)

        • Công dụng: Dùng để lấy giá trị thứ nhất trừ đi giá trị thứ hai.
        • Ví dụ cơ bản:
        let tongTien = 50000;
        const giamGia = 10000;
        const tienPhaiTra = tongTien - giamGia;
        
        console.log(`Số tiền phải trả sau khi giảm giá: ${tienPhaiTra}đ`); // Kết quả: 40000đ

        3. Phép Nhân (*)

        • Công dụng: Dùng để nhân hai giá trị với nhau.
        • Ví dụ cơ bản:
        const donGiaAo = 250000;
        const soLuong = 3;
        const thanhTien = donGiaAo * soLuong;
        
        console.log(`Thành tiền cho ${soLuong} cái áo là: ${thanhTien}đ`); // Kết quả: 750000đ

        4. Phép Chia (/)

        • Công dụng: Dùng để lấy giá trị thứ nhất chia cho giá trị thứ hai. Kết quả có thể là số nguyên hoặc số thập phân.
        • Ví dụ cơ bản:
        onst tongSoKeo = 20;
        const soNguoi = 4;
        const keoMoiNguoi = tongSoKeo / soNguoi;
        
        console.log(`Mỗi người sẽ nhận được: ${keoMoiNguoi} cái kẹo`); // Kết quả: 5 cái kẹo

        5. Phép Chia Lấy Dư (%) - Modulo

        • Công dụng: Trả về phần dư của một phép chia. Nó rất hữu ích để kiểm tra tính chẵn lẻ hoặc các bài toán lặp đi lặp lại.
        • Ví dụ cơ bản:
        const tongSoBanh = 10;
        const soBanhMoiHop = 3;
        const soBanhConLai = tongSoBanh % soBanhMoiHop;
        
        console.log(`Sau khi xếp bánh vào các hộp, số bánh còn lại là: ${soBanhConLai}`); // Kết quả:
        
        Ứng dụng phổ biến (Kiểm tra chẵn/lẻ): Một số là chẵn nếu nó chia hết cho 2 (tức là soCanKiemTra % 2 === 0).
        
        const soCanKiemTra = 7;
        const laSoChan = soCanKiemTra % 2 === 0;
        console.log(`Số ${soCanKiemTra} có phải là số chẵn không? ${laSoChan}`); // Kết quả: false

        Ứng dụng chung trong Automation

        Trong kịch bản test, bạn thường xuyên kết hợp các phép tính này để xác thực dữ liệu.

        // Kịch bản: Kiểm tra chức năng giỏ hàng
        const donGia = 250000;
        const soLuong = 3;
        const phiShip = 30000;
        
        // Dùng phép nhân (*) để tính tiền hàng
        const tienHang = donGia * soLuong;
        // Dùng phép cộng (+) để tính tổng hóa đơn
        const tongHoaDon = tienHang + phiShip;
        
        console.log(`Tiền hàng: ${tienHang}đ`);
        console.log(`Tổng hóa đơn (bao gồm ship): ${tongHoaDon}đ`);
        // Ở các bước test sau, bạn sẽ lấy con số thực tế từ web và so sánh với biến `tongHoaDon`.

         

        Ép kiểu dữ liệu 

        Đây là một kỹ năng sống còn vì dữ liệu bạn lấy từ trang web luôn là kiểu string (chuỗi). "Ép kiểu" là quá trình chuyển đổi một giá trị từ kiểu dữ liệu này sang kiểu khác để có thể tính toán chính xác.

        Định nghĩa chung: Sự "hai mặt" của các toán tử

        Hãy tưởng tượng các toán tử có những "tính cách" khác nhau khi gặp phải chuỗi.

        • Toán tử cộng (+): "Người thợ dán keo"
          • Quy tắc: Nếu có ít nhất một giá trị là chuỗi, + sẽ ưu tiên nối chuỗi. Nó sẽ biến mọi thứ khác thành chuỗi để "dán" chúng lại với nhau.
          • Ví dụ:
        console.log("5" + 5);      // "55" (chuỗi)
        console.log(1 + 2 + "3");  // "33" (chuỗi)
        • Các toán tử khác (-, *, /, %): "Những nhà toán học"
          • Quy tắc: Các toán tử này sẽ luôn cố gắng chuyển đổi các giá trị thành số để thực hiện phép tính.
          • Ví dụ:
        console.log("10" - 5);    // 5 (số)
        console.log("10" * "2");  // 20 (số)

        Sự không nhất quán này chính là lý do chúng ta không bao giờ nên dựa vào ép kiểu tự động.

        Giải pháp: Chủ động ép kiểu & Quy trình chuẩn trong Automation

        Cách làm an toàn và chuyên nghiệp nhất là luôn chủ động chuyển đổi kiểu dữ liệu.

        Bộ công cụ ép kiểu:

        • Number(value): Dùng khi bạn chắc chắn chuỗi đã được làm sạch và chỉ chứa số. Nó rất nghiêm ngặt.
        • parseInt(value): Dùng để lấy số nguyên từ một chuỗi (ví dụ: "100px" -> 100).
        • parseFloat(value): Dùng để lấy số thập phân từ một chuỗi (ví dụ: "25.99 USD" -> 25.99).

        Ví dụ ứng dụng trong Automation:

        Kịch bản: Kịch bản test của bạn cần xác thực tổng tiền trong giỏ hàng.

        // Bước 1: Dữ liệu lấy về từ web (luôn là chuỗi và không sạch sẽ)
        const giaTienText = "Giá: 25.99 USD";
        const soLuongText = "3 items";
        const phiShipText = "Phí vận chuyển: $5.50";
        
        // Bước 2: "Sơ chế" dữ liệu bằng các phương thức từ Bài 4
        const giaTienClean = giaTienText.replace("Giá: ", "").replace(" USD", "");     // "25.99"
        const soLuongClean = soLuongText.replace(" items", "");                         // "3"
        const phiShipClean = phiShipText.replace("Phí vận chuyển: $", "");             // "5.50"
        
        // Bước 3: Chủ động ép kiểu bằng công cụ phù hợp
        const giaTienNumber = parseFloat(giaTienClean); // Dùng parseFloat cho giá tiền có số lẻ
        const soLuongNumber = parseInt(soLuongClean);   // Dùng parseInt cho số lượng là số nguyên
        
        // Dùng Number() cho phí ship vì chuỗi đã sạch hoàn toàn
        const phiShipNumber = Number(phiShipClean);
        
        // Bước 4: Thực hiện các phép toán một cách an toàn
        const tienHang = giaTienNumber * soLuongNumber;
        const tongHoaDon = tienHang + phiShipNumber;
        
        // In ra kết quả để xác thực ở các bước tiếp theo
        console.log(`Tiền hàng dự kiến: ${tienHang.toFixed(2)}`);
        console.log(`Tổng hóa đơn dự kiến: ${tongHoaDon.toFixed(2)}`);

         

        Number() - "Người bảo vệ nghiêm ngặt"

        Hàm Number() cực kỳ khó tính. Nó yêu cầu toàn bộ chuỗi bạn đưa cho nó phải là một con số hợp lệ, chỉ cho phép có khoảng trắng thừa ở đầu hoặc cuối. Nếu nó phát hiện bất kỳ ký tự nào không phải là số (ngoài dấu . hoặc -), nó sẽ từ chối ngay lập tức và trả về NaN.

        • Number("25.99") → ✅ Hợp lệ, kết quả là 25.99.
        • Number(" 25.99 ") → ✅ Hợp lệ, nó tự bỏ qua khoảng trắng, kết quả là 25.99.
        • Number("25.99 USD") → ❌ Không hợp lệ! Nó thấy có chữ "USD" nên từ chối toàn bộ. Kết quả là NaN.
        • Number("Giá: 25.99") → ❌ Không hợp lệ! Nó thấy có chữ "Giá: " ở đầu. Kết quả là NaN.

        parseFloat() - "Người trợ lý hữu ích"

        Hàm parseFloat() thì linh hoạt hơn. Nó sẽ đọc chuỗi của bạn từ trái sang phải và lấy ra con số thập phân đầu tiên nó tìm thấy. Khi nó gặp một ký tự không phải là số (mà không phải là dấu chấm thập phân đầu tiên), nó sẽ dừng lại và trả về kết quả đã đọc được.

        • parseFloat("25.99 USD") → ✅ Hợp lệ! Nó đọc 25.99, gặp khoảng trắng và dừng lại. Kết quả là 25.99.
        • parseFloat("100px") → ✅ Hợp lệ! Nó đọc 100, gặp chữ p và dừng lại. Kết quả là 100.
        • parseFloat("Giá là 25.99") → ❌ Không hợp lệ! Vì chuỗi bắt đầu bằng chữ, nó không tìm thấy số nào để đọc ngay từ đầu. Kết quả là NaN.

        parseInt() - "Chuyên gia bóc tách số nguyên"

        Hàm parseInt() cũng là một "trợ lý hữu ích" giống parseFloat(), nhưng nó chỉ quan tâm đến số nguyên.

        • Cách hoạt động: Nó đọc chuỗi từ trái sang phải và lấy ra số nguyên đầu tiên tìm thấy. Nó sẽ dừng lại ngay khi gặp ký tự không phải là số, bao gồm cả dấu chấm thập phân.

        So sánh trực tiếp:

        const giaTienText = "25.99 USD";
        
        console.log(parseFloat(giaTienText)); // 25.99 (Đọc cả phần thập phân)
        console.log(parseInt(giaTienText));   // 25 (Dừng lại ở dấu '.')
        console.log(Number(giaTienText));     // NaN (Thất bại vì có chữ " USD")

        isNaN() vs Number.isNaN() - Hai cách kiểm tra "Không phải là số"

        Khi một phép chuyển đổi kiểu thất bại, kết quả thường là NaN (Not a Number). Nhưng việc kiểm tra xem một giá trị có phải là NaN hay không lại có hai cách, và chúng hoạt động khác nhau.

        isNaN() (Hàm toàn cục) - "Người trợ lý dễ dãi"

        Đây là hàm có sẵn từ lâu. Trước khi kiểm tra, nó sẽ cố gắng ép kiểu giá trị đầu vào thành số. Nếu ép kiểu thất bại (ra NaN), nó sẽ trả về true.

        • Cách hoạt động: "Bạn có thể trở thành một con số không? Nếu không, bạn là NaN."
        • Ví dụ:
        console.log(isNaN(123));          // false (123 là số)
        console.log(isNaN("123"));        // false (Vì "123" có thể ép kiểu thành số 123)
        console.log(isNaN("hello"));      // true (Vì "hello" không thể ép kiểu thành số)
        console.log(isNaN(undefined));    // true (Vì undefined không thể ép kiểu thành số)

        Hành vi tự động ép kiểu này có thể dẫn đến kết quả khó đoán.

        Number.isNaN() (Phương thức của Number) - "Chuyên gia nghiêm ngặt"

        Đây là phương thức hiện đại và an toàn hơn. Nó không ép kiểu. Nó chỉ đơn giản kiểm tra xem giá trị bạn đưa vào có chính xác là giá trị đặc biệt NaN hay không.

        • Cách hoạt động: "Bạn có chính xác là NaN không?"
        • Ví dụ:
        let ketQua = Number("hello"); // Phép chuyển đổi này tạo ra NaN
        console.log(ketQua); // NaN
        
        // Chỉ trả về true khi giá trị là NaN
        console.log(Number.isNaN(ketQua));    // true
        
        // Các trường hợp khác đều là false vì chúng không phải là giá trị NaN
        console.log(Number.isNaN("hello"));   // false
        console.log(Number.isNaN(123));       // false
        console.log(Number.isNaN("123"));     // false

        Tổng kết và Lời khuyên

        Quy tắc vàng:

        1. Khi cần trích xuất một số từ chuỗi có ký tự lạ ở cuối, hãy dùng parseInt() (cho số nguyên) hoặc parseFloat() (cho số thập phân).
        2. Khi cần kiểm tra một giá trị có phải là NaN hay không, hãy luôn dùng phương thức an toàn và hiện đại là Number.isNaN().

         

         

        ✅Phần 5: Toán tử Gán (Assignment Operators)

        Sau khi đã làm chủ các phép toán số học, bây giờ chúng ta sẽ đi sâu vào các loại toán tử khác. Đây là những công cụ giúp bạn gán giá trị, so sánh dữ liệu và tạo ra các logic phức tạp – những kỹ năng cốt lõi của một kịch bản automation thông minh.

        Định nghĩa chung

        Toán tử gán được sử dụng để gán giá trị cho các biến. Ngoài toán tử gán cơ bản là dấu bằng (=), JavaScript còn cung cấp các toán tử gán rút gọn rất tiện lợi.

        Toán tử

        Ví dụ

        Tương đương với

        =

        x = 10

        x = 10

        +=

        x += 5

        x = x + 5

        -=

        x -= 5

        x = x - 5

        *=

        x *= 2

        x = x * 2

         

        // Ví dụ cơ bản
        let diemSo = 5;
        diemSo += 3; // diemSo bây giờ là 5 + 3 = 8
        console.log(`Điểm số sau khi cộng thưởng: ${diemSo}`); // 8​

        Ứng dụng trong Automation

        Bạn thường xuyên dùng các toán tử này để cập nhật trạng thái hoặc cộng dồn các giá trị trong kịch bản test.

        // Kịch bản: Tính tổng giá trị các sản phẩm trong giỏ hàng
        let tongTien = 0;
        const giaSanPham1 = 150000;
        const giaSanPham2 = 300000;
        
        tongTien += giaSanPham1; // tongTien bây giờ là 150000
        tongTien += giaSanPham2; // tongTien bây giờ là 150000 + 300000 = 450000
        
        console.log(`Tổng tiền hàng trong giỏ là: ${tongTien}đ`);

         

        Toán tử Tăng/Giảm (Increment/Decrement Operators)

        Định nghĩa chung

        Đây là cách viết tắt cực kỳ ngắn gọn để cộng hoặc trừ đi 1, rất phổ biến trong các vòng lặp hoặc khi đếm số lần thực hiện một hành động.

        • ++ (Tăng): Tăng giá trị của biến lên 1. x++ tương đương với x = x + 1.
        • -- (Giảm): Giảm giá trị của biến đi 1. x-- tương đương với x = x - 1.

        Tuy nhiên, có hai cách để sử dụng chúng: Hậu tố (postfix) và Tiền tố (prefix), và chúng khác nhau ở giá trị mà chúng trả về trong một biểu thức.

        Hậu tố (Postfix): x++

        Đây là dạng phổ biến nhất. "Hậu" có nghĩa là "sau".

        • Quy tắc: "Trả về giá trị CŨ, sau đó mới tăng."
        • Diễn giải: JavaScript sẽ lấy giá trị hiện tại của x để sử dụng trong biểu thức trước, và chỉ sau khi dòng lệnh đó kết thúc, nó mới cập nhật giá trị của x lên 1.
        • Ví dụ cơ bản:

         

        let x = 10;
        
        // Ở đây, giá trị CŨ của x (là 10) được trả về và gán cho y.
        let y = x++;
        
        console.log(`Giá trị của y là: ${y}`); // y nhận giá trị cũ của x
        console.log(`Giá trị của x sau đó là: ${x}`); // x đã được tăng lên
        Kết quả:
        Giá trị của y là: 10
        Giá trị của x sau đó là: 11​

        Tiền tố (Prefix): ++x

        "Tiền" có nghĩa là "trước".

        • Quy tắc: "Tăng giá trị TRƯỚC, sau đó trả về giá trị MỚI."
        • Diễn giải: JavaScript sẽ tăng giá trị của x lên 1 ngay lập tức, sau đó mới dùng giá trị mới đó để sử dụng trong biểu thức.
        • Ví dụ cơ bản:
        let a = 10;
        
        // Ở đây, a được tăng lên 11 TRƯỚC, sau đó giá trị MỚI (là 11) được gán cho b.
        let b = ++a;
        
        console.log(`Giá trị của b là: ${b}`); // b nhận giá trị mới của a   
        console.log(`Giá trị của a sau đó là: ${a}`); // a vẫn là 11
        Kết quả:
        Giá trị của b là: 11
        Giá trị của a sau đó là: 11


        Giải thích chi tiết: Hậu tố (x++) vs. Tiền tố (++x)

        Cả hai đều làm một việc: tăng giá trị của biến x lên 1. Nhưng chúng khác nhau ở thứ tự thực hiện hành động.

        Trường hợp 1: Sử dụng trong một phép gán (=)

        Đây là trường hợp rõ ràng nhất để thấy sự khác biệt.

        let soLuongHienTai = 5;
        
        // Bước 1: Giá trị CŨ của `soLuongHienTai` (là 5) được gán cho `soLuongDaGhiNhan` TRƯỚC.
        // Bước 2: SAU ĐÓ, `soLuongHienTai` mới được tăng lên 6.
        let soLuongDaGhiNhan = soLuongHienTai++;
        
        console.log(`Số lượng đã ghi nhận để xử lý: ${soLuongDaGhiNhan}`);
        console.log(`Số lượng hiện tại thực tế trong kho: ${soLuongHienTai}`);
        
        Kết quả:
        Số lượng đã ghi nhận để xử lý: 5
        Số lượng hiện tại thực tế trong kho: 6

       

      Ứng dụng: Hữu ích khi bạn muốn lấy giá trị hiện tại để dùng ngay, và sau đó mới cập nhật biến đếm cho lần sau.

      • Tiền tố (++soLuong): "Anh cập nhật trước đi, rồi đưa tôi giá trị MỚI nhất"

       

      let soLuongHienTai_2 = 5;
      
      // Bước 1: `soLuongHienTai_2` được tăng lên 6 TRƯỚC.
      // Bước 2: SAU ĐÓ, giá trị MỚI (là 6) được gán cho `soLuongDaGhiNhan_2`.
      let soLuongDaGhiNhan_2 = ++soLuongHienTai_2;
      
      console.log(`Số lượng đã ghi nhận để xử lý: ${soLuongDaGhiNhan_2}`);
      console.log(`Số lượng hiện tại thực tế trong kho: ${soLuongHienTai_2}`);
      
      Kết quả:
      Số lượng đã ghi nhận để xử lý: 6
      Số lượng hiện tại thực tế trong kho: 6​

      Ứng dụng: Hữu ích khi bạn muốn cập nhật biến đếm ngay lập tức và sử dụng giá trị vừa được cập nhật đó cho các bước tiếp theo.

      Trường hợp 2: Sử dụng trực tiếp trong console.log()

      Hành vi tương tự như phép gán. console.log sẽ nhận được giá trị trả về của biểu thức.

      • Hậu tố (soLanClick++):
      let soLanClick = 0;
      
      // In ra giá trị CŨ (0), SAU ĐÓ soLanClick tăng lên 1
      console.log(`Bắt đầu click lần thứ: ${soLanClick++}`);
      
      // In ra giá trị CŨ (1), SAU ĐÓ soLanClick tăng lên 2
      console.log(`Bắt đầu click lần thứ: ${soLanClick++}`);
      
      console.log(`Tổng số lần đã click: ${soLanClick}`);
      
      Kết quả:
      Bắt đầu click lần thứ: 0
      Bắt đầu click lần thứ: 1
      Tổng số lần đã click: 2​

       Rủi ro trong Automation: Log này có thể gây hiểu nhầm. Nó ghi là "click lần thứ 0" trong khi thực tế đó là lần click đầu tiên.

      • Tiền tố (++soLanRetry):
      let soLanRetry = 0;
      
      // Tăng soLanRetry lên 1 TRƯỚC, SAU ĐÓ in ra giá trị MỚI (1)
      console.log(`Thử lại lần thứ: ${++soLanRetry}`);
      
      // Tăng soLanRetry lên 2 TRƯỚC, SAU ĐÓ in ra giá trị MỚI (2)
      console.log(`Thử lại lần thứ: ${++soLanRetry}`);
      
      console.log(`Tổng số lần đã thử lại: ${soLanRetry}`);
      
      Kết quả:
      Thử lại lần thứ: 1
      Thử lại lần thứ: 2
      Tổng số lần đã thử lại: 2
      •  Hữu ích trong Automation: Log này rõ ràng và chính xác hơn, phản ánh đúng số lần đã thử lại.

      Trường hợp 3: Sử dụng độc lập trên một dòng (Cách được khuyên dùng)

      Khi bạn đặt toán tử tăng/giảm trên một dòng riêng, không có phép gán hay console.log nào kèm theo, thì hành vi của hậu tố và tiền tố là hoàn toàn giống nhau.

      let counter1 = 0;
      counter1++; // Tăng counter1 lên 1.
      console.log(counter1); // 1
      
      let counter2 = 0;
      ++counter2; // Cũng tăng counter2 lên 1.
      console.log(counter2); // 1

       

      Ứng dụng và Lời khuyên cho Automation 

      Sự khác biệt này quan trọng về mặt kỹ thuật, nhưng việc sử dụng chúng trong một biểu thức phức tạp có thể làm code khó đọc và dễ gây lỗi.

      Quy tắc vàng: Trong 99% các trường hợp khi viết test automation, bạn chỉ cần tăng giá trị của một biến (như biến đếm). Vì vậy, để code đơn giản và dễ đọc nhất, hãy luôn sử dụng hậu tố (x++) và đặt nó trên một dòng riêng.

      Cách làm được khuyên dùng (Rõ ràng và an toàn):

      // Kịch bản: Đếm số lần thử lại một hành động thất bại
      let soLanRetry = 0;
      
      // ... giả lập hành động test bị thất bại ...
      console.log("Hành động thất bại, bắt đầu thử lại...");
      
      // Tăng số lần retry lên một cách rõ ràng trên một dòng riêng.
      soLanRetry++;
      
      console.log(`Đã thử lại ${soLanRetry} lần.`);

       

      Bằng cách này, bạn không cần phải bận tâm về sự khác biệt giữa tiền tố và hậu tố, và code của bạn sẽ luôn rõ ràng cho bất kỳ ai đọc nó.

      Toán tử So sánh (Comparison Operators) - Trái tim của Automation

      Đây là phần quan trọng nhất. Các toán tử này so sánh hai giá trị và luôn trả về một giá trị boolean (true hoặc false), làm nền tảng cho mọi câu lệnh kiểm tra (assertion).

      Toán tử

      Tên gọi

      >, <, >=, <=

      Lớn hơn, nhỏ hơn, lớn hơn hoặc bằng, nhỏ hơn hoặc bằng

      ==, !=

      Bằng, không bằng (Lỏng lẻo)

      ===, !==

      Bằng, không bằng (Nghiêm ngặt)

      Trọng tâm: So sánh bằng == vs === 

      Đây là một trong những điểm dễ gây ra lỗi ngầm nhất trong JavaScript nếu không hiểu rõ.

      == (So sánh lỏng lẻo): "Người bảo vệ dễ tính"

      console.log(5 == "5"); // true
      // JavaScript nghĩ: "À, một bên là số, một bên là chuỗi.
      // Để so sánh, mình sẽ biến chuỗi '5' thành số 5.
      // Bây giờ phép so sánh là 5 == 5, kết quả là true."
      
      console.log(0 == false); // true
      // JavaScript tự động ép kiểu `false` thành `0`.​​

      Hành vi tự động này có thể che giấu các lỗi về kiểu dữ liệu trong chương trình của bạn.

      === (So sánh nghiêm ngặt): "Người bảo vệ chuyên nghiệp"

      • Định nghĩa chung: Toán tử này so sánh cả giá trị VÀ kiểu dữ liệu. Nó không bao giờ tự động ép kiểu.
      • Ví dụ cơ bản:
      console.log(5 === "5"); // false
      // JavaScript nghĩ: "Một bên là number, một bên là string.
      // Kiểu dữ liệu khác nhau, không cần so sánh giá trị nữa. Kết quả là false."
      
      console.log(0 === false); // false
      // Kiểu dữ liệu khác nhau (number vs boolean).

       

      Quy tắc vàng: Để đảm bảo kịch bản test của bạn luôn chính xác, không có lỗi ngầm và dễ đoán, hãy luôn luôn sử dụng so sánh nghiêm ngặt === và !== (không bằng nghiêm ngặt).

      Ứng dụng trong Automation

      Mọi câu lệnh kiểm tra (ví dụ: expect trong Playwright) đều hoạt động dựa trên nguyên tắc so sánh nghiêm ngặt này.

      Kịch bản: Kịch bản của bạn cần xác thực số lượng sản phẩm trong giỏ hàng và giá của một sản phẩm.

      // Dữ liệu mong đợi trong kịch bản test
      const soLuongMongDoi = 5; // number
      const giaTienMongDoi = 250000; // number
      
      // Dữ liệu thực tế lấy về từ trang web (luôn là string)
      const soLuongThucTe_text = "5";
      const giaTienThucTe_text = "250,000đ";
      
      // Bước 1: Sơ chế và chuyển đổi kiểu dữ liệu của giá trị thực tế
      const soLuongThucTe_number = parseInt(soLuongThucTe_text);
      const giaTienThucTe_number = parseInt(giaTienThucTe_text.replaceAll(",", "").replace("đ", ""));
      
      // Bước 2: Dùng so sánh nghiêm ngặt (===) để xác thực
      const ketQuaTestSoLuong = soLuongMongDoi === soLuongThucTe_number;
      const ketQuaTestGiaTien = giaTienMongDoi === giaTienThucTe_number;
      
      console.log(`Kết quả kiểm tra số lượng có khớp không? ${ketQuaTestSoLuong}`);
      console.log(`Kết quả kiểm tra giá tiền có khớp không? ${ketQuaTestGiaTien}`);
      
      Bằng cách chủ động chuyển đổi kiểu dữ liệu rồi sau đó dùng ===, bạn đảm bảo rằng kịch bản test của mình đang so sánh chính xác "táo với táo" chứ không phải "táo với một bức tranh vẽ quả táo".​

      Toán tử Logic (Logical Operators) - Kết hợp các điều kiện

      Sau khi đã biết cách "đặt câu hỏi" bằng các toán tử so sánh (Phần 3), chúng ta cần công cụ để kết hợp nhiều câu hỏi lại với nhau. Toán tử logic chính là "chất keo" giúp bạn tạo ra những quy tắc kiểm tra phức tạp và thông minh hơn.

      1. && (AND - Và)

      Định nghĩa chung

      Toán tử && sẽ trả về true chỉ khi tất cả các điều kiện đều là true. Nếu có dù chỉ một điều kiện là false, kết quả cuối cùng sẽ là false.

      • Ví von: 🧠 Để được vào xem phim, bạn cần có vé && bạn phải đến đúng giờ. Thiếu một trong hai là không được vào.

      Ví dụ cơ bản:

      const coVeXemPhim = true;
      const denDungGio = true;
      const duocVaoXem = coVeXemPhim && denDungGio;
      console.log(`Được vào xem phim không? ${duocVaoXem}`); // true
      
      const coVeKhac = true;
      const denMuon = false;
      const khongDuocVao = coVeKhac && denMuon;
      console.log(`Một trường hợp khác, được vào xem không? ${khongDuocVao}`); // false

       

      Ứng dụng trong Automation

      Đây là toán tử bạn sẽ dùng liên tục. Một hành động trong kịch bản test thường chỉ được thực hiện khi nhiều điều kiện tiên quyết được thỏa mãn.

      • Kịch bản: Kịch bản của bạn chỉ nên click vào nút "Đăng nhập" khi nút đó vừa hiển thị trên màn hình VÀ có thể được tương tác (không bị vô hiệu hóa).

      Ví dụ Automation:

      // Giả lập trạng thái của nút lấy từ Playwright
      const nutDangNhapIsVisible = true;
      const nutDangNhapIsEnabled = true;
      
      // Kết hợp hai điều kiện bằng toán tử &&
      const coTheClickNutDangNhap = nutDangNhapIsVisible && nutDangNhapIsEnabled;
      
      console.log(`Điều kiện để click nút Đăng nhập đã thỏa mãn chưa? ${coTheClickNutDangNhap}`);
      // Chỉ khi biến này là true, kịch bản của bạn mới thực hiện lệnh page.click()

      2. || (OR - Hoặc)

      Định nghĩa chung

      Toán tử || sẽ trả về true chỉ cần ít nhất một trong các điều kiện là true. Nó chỉ trả về false khi tất cả các điều kiện đều là false.

      • Ví von: 🧠 Để thanh toán, bạn có thể dùng thẻ tín dụng || bạn có thể dùng ví điện tử. Chỉ cần có một trong hai là được.

      Ví dụ cơ bản:

      const coTheTinDung = false;
      const coViDienTu = true;
      const coTheThanhToan = coTheTinDung || coViDienTu;
      console.log(`Có thể thanh toán được không? ${coTheThanhToan}`); // true

       

      Ứng dụng trong Automation

      Rất hữu ích khi một kết quả mong muốn có thể tồn tại dưới nhiều dạng khác nhau.

      • Kịch bản: Sau khi đặt hàng thành công, thông báo hiển thị có thể là "Đặt hàng thành công!" hoặc "Cảm ơn bạn đã mua hàng!". Kịch bản test sẽ pass nếu một trong hai thông báo này xuất hiện.

      Ví dụ Automation:

      // Giả lập text thông báo lấy từ trang web
      const thongBaoThucTe = "Đặt hàng thành công!";
      
      // Kiểm tra xem text thực tế có khớp với một trong các khả năng hay không
      const laThongBaoDung = (thongBaoThucTe === "Đặt hàng thành công!") || (thongBaoThucTe === "Cảm ơn bạn đã mua hàng!");
      
      console.log(`Thông báo thành công có hợp lệ không? ${laThongBaoDung}`); // true​

      3. ! (NOT - Phủ định)

      Định nghĩa chung

      Toán tử ! đơn giản là lật ngược giá trị boolean từ true thành false, và từ false thành true.

      • Ví von: 🧠 Nó giống như một "công tắc đảo chiều".

      Ví dụ cơ bản:

      const cuaDangMo = true;
      const cuaDangDong = !cuaDangMo; // Phủ định của true là false
      console.log(`Cửa đang đóng? ${cuaDangDong}`); // false

      Ứng dụng trong Automation

      Cực kỳ hữu ích khi bạn cần kiểm tra sự vắng mặt của một thứ gì đó. Đây là một hành động kiểm tra rất phổ biến.

      • Kịch bản: Kịch bản của bạn phải chờ cho đến khi biểu tượng "đang tải" (loading spinner) biến mất khỏi màn hình rồi mới được thực hiện bước tiếp theo.

      Ví dụ Automation:

      // Giả lập trạng thái: sau khi chờ, spinner không còn hiển thị nữa
      const spinnerIsVisible = false;
      // Dùng phủ định để kiểm tra điều kiện "KHÔNG hiển thị"
      const coTheTiepTuc = !spinnerIsVisible;
      console.log(`Có thể thực hiện bước tiếp theo không? ${coTheTiepTuc}`); // true
      // Chỉ khi biến này là true, kịch bản mới tiếp tục.

       

      Thứ tự ưu tiên của các toán tử trong JavaScript (Operator Precedence)

      Giống như trong toán học ở trường, bạn học quy tắc "nhân chia trước, cộng trừ sau", JavaScript cũng có một bộ quy tắc tương tự để quyết định phép toán nào sẽ được thực hiện trước. Việc hiểu rõ thứ tự này sẽ giúp bạn tránh được những lỗi logic khó tìm.

      Bảng thứ tự ưu tiên (Từ cao đến thấp)

      Dưới đây là bảng xếp hạng độ ưu tiên của các toán tử chúng ta đã học, từ cao nhất (thực hiện trước) đến thấp nhất (thực hiện sau).

      Mức ưu tiên

      Loại toán tử

      Toán tử

      Cao nhất (1)

      Dấu ngoặc (Grouping)

      ( ... )

      2

      Truy cập thuộc tính, Hàm

      ., ()

      3

      Tăng/Giảm, Phủ định, typeof

      ++, --, !, typeof

      4

      Lũy thừa

      **

      5

      Nhân / Chia / Chia lấy dư

      *, /, %

      6

      Cộng / Trừ

      +, -

      7

      So sánh quan hệ

      >, <, >=, <=

      8

      So sánh bằng

      ===, !==

      9

      Logic AND

      &&

      10

      Logic OR

      `

      Thấp nhất (11)

      Gán (Assignment)

      =, +=, -=

      Điểm cần nhớ:

      • Phép nhân/chia luôn được ưu tiên hơn cộng/trừ.
      • Các phép so sánh được thực hiện sau các phép toán số học.
      • Phép && (Và) được ưu tiên hơn phép || (Hoặc).
      • Phép gán (=) luôn luôn được thực hiện cuối cùng.

      Ví dụ phân tích từng bước

      Hãy xem cách JavaScript "đọc" một biểu thức phức tạp trong một kịch bản automation.

      Kịch bản: Xác định xem một khách hàng có đủ điều kiện nhận "Ưu đãi Giao hàng miễn phí" hay không.

      // Dữ liệu đầu vào
      const giaTien = 100;
      const soLuong = 2;
      const phiShip = 30;
      const daDangNhap = true;
      const laThanhVienVIP = false;
      
      // Biểu thức phức tạp cần phân tích
      let duocUuDai = giaTien * soLuong + phiShip > 200 && daDangNhap || laThanhVienVIP;
      
      JavaScript sẽ không đọc từ trái sang phải, mà nó sẽ thực hiện theo thứ tự ưu tiên như sau:
      Bước 1: Phép nhân * (Mức 5)
      100 * 2 → 200
      Biểu thức trở thành: 200 + phiShip > 200 && daDangNhap || laThanhVienVIP
      Bước 2: Phép cộng + (Mức 6)
      200 + 30 → 230
      Biểu thức trở thành: 230 > 200 && daDangNhap || laThanhVienVIP
      Bước 3: Phép so sánh > (Mức 7)
      230 > 200 → true
      Biểu thức trở thành: true && daDangNhap || laThanhVienVIP
      Bước 4: Phép && (Mức 9)
      true && true → true
      Biểu thức trở thành: true || laThanhVienVIP
      Bước 5: Phép || (Mức 10)
      true || false → true
      Biểu thức trở thành: true
      Bước 6: Phép gán = (Mức 11)
      duocUuDai = true
      Biến duocUuDai cuối cùng nhận giá trị true.​

      Quy tắc vàng: "Khi không chắc chắn, hãy dùng dấu ngoặc ()" 

      Việc ghi nhớ toàn bộ bảng trên là không cần thiết và có thể làm cho code của bạn khó đọc. Cách làm tốt nhất của các lập trình viên chuyên nghiệp là:

      Sử dụng dấu ngoặc () để nhóm các phép toán và làm rõ ý định của bạn.

      Dấu ngoặc có độ ưu tiên cao nhất, vì vậy mọi thứ bên trong nó sẽ được thực hiện trước.

      Hãy viết lại ví dụ trên với dấu ngoặc để code trở nên dễ hiểu hơn ngay lập tức:

      let duocUuDai_roRang = (((giaTien * soLuong + phiShip) > 200) && daDangNhap) || laThanhVienVIP;

       

      Khi đọc dòng code này, bất kỳ ai cũng có thể hiểu ngay lập tức rằng:

      1. Đầu tiên, tính tổng giá trị đơn hàng (giaTien * soLuong + phiShip).
      2. Sau đó, so sánh tổng đó với 200.
      3. Kết quả so sánh đó được && với daDangNhap.
      4. Cuối cùng, toàn bộ kết quả của vế trái được || với laThanhVienVIP.

      Việc dùng dấu ngoặc không chỉ giúp tránh lỗi do nhầm lẫn thứ tự ưu tiên mà còn làm cho code của bạn sáng sủa và dễ bảo trì hơn rất nhiều.

       

Teacher

Teacher

Nguyên Hoàng

Automation Engineer

With 7+ years of hands-on experience across multiple languages and frameworks. I'm here to share knowledge, helping you turn complex processes into simple and effective solutions.

Cộng đồng Automation Testing Việt Nam:

🌱 Telegram Automation Testing:   Cộng đồng Automation Testing
🌱 
Facebook Group Automation: Cộng đồng Automation Testing Việt Nam
🌱 
Facebook Fanpage: Cộng đồng Automation Testing Việt Nam - Selenium
🌱 Telegram
Manual Testing:   Cộng đồng Manual Testing
🌱 
Facebook Group Manual: Cộng đồng Manual Testing Việt Nam

Chia sẻ khóa học lên trang

Bạn có thể đăng khóa học của chính bạn lên trang Anh Tester để kiếm tiền

Danh sách bài học