Với tư duy của một người làm SEO/Growth, xử lý Chuỗi (String) chính là kỹ năng hái ra tiền (tạo Slug URL chuẩn SEO, bắt tham số UTM, làm sạch dữ liệu form). Tôi đã mổ xẻ
1. STRING (CHUỖI) — Nghệ Thuật Nhào Nặn Văn Bản
Chuỗi là dữ liệu văn bản. Trong JS, chuỗi là "bất biến" (immutable) - tức là các hàm xử lý chuỗi sẽ không làm thay đổi chuỗi gốc, mà nó luôn đẻ ra một chuỗi mới. (Nhớ kỹ đặc tính này để luôn gắn biến hứng kết quả, ví dụ: text = text.trim()).
1.1. Template Literals (Chuỗi nội suy bằng dấu `)
Kẻ hủy diệt phép cộng chuỗi + lằng nhằng thời tiền sử.
Cơ học: Dùng dấu backtick
`bọc ngoài. Chỗ nào cần nhét biến JS vào thì bọc bằng${...}.Ứng dụng thực tế (Bài tập
buildProductUrl): Thay vì viếtbaseUrl + "/" + product.category + "?id=" + product.id(rất dễ gõ thiếu dấu slash hoặc dấu hỏi), bạn chỉ cần:
const url = `${baseUrl}/${product.category}/${product.slug}?id=${product.id}`;1.2. Biến Hình Nhân Dạng (Case Conversion)
.toLowerCase(): Ép văng mọi chữ hoa thành chữ thường.- Thực chiến: Bắt buộc dùng làm bước đầu tiên khi tạo URL Slug (Bài tập
createSlug). .toUpperCase(): Ép thành in hoa toàn bộ.- Thực chiến: Dùng để tạo mã đơn hàng luôn viết hoa (Bài tập
generateOrderId).
1.3. Cưa Cắt & Gọt Dũa
.trim(): Gọt sạch khoảng trắng vô duyên ở hai đầu chuỗi.- Thực chiến: Luôn dùng khi lấy dữ liệu từ Form người dùng nhập vào để tránh lỗi khoảng trắng dư.
.slice(vị_trí_bắt_đầu, vị_trí_kết_thúc): Cắt lấy một khúc thịt của chuỗi.- Cơ học:
.slice(0, 3)sẽ lấy ký tự ở index 0, 1, 2 (không lấy index 3). - Thực chiến: Lấy 3 chữ cái đầu tiên của tên sản phẩm để làm mã (Bài tập
generateOrderId).
1.4. Thanh Trừng & Thay Thế (Quyền lực tối thượng)
.replace("cũ", "mới"): Thay thế từ ngữ. Nhưng theo bản mặc định, nó cực kỳ lười: chỉ thay đúng 1 chữ đầu tiên nó thấy..replaceAll("cũ", "mới"): Quét sạch sành sanh và thay thế toàn bộ.Hack bằng Regex (Biểu thức chính quy): Trong bài tạo Slug (
createSlug), bạn phải xóa bỏ ký tự đặc biệt (chỉ giữ lại chữ, số và dấu-). JS thuần không có hàm nào tên là "xóa ký tự đặc biệt". Bạn phải dùng phép thuật Regex truyền vào hàmreplace:- Công thức:
text.replace(/[^a-z0-9\-]/g, "") [^...]nghĩa là "NGOẠI TRỪ". Lệnh này bảo máy tính: "Tìm tất cả những thằng KHÔNG PHẢI là chữ từ a-z, KHÔNG PHẢI số 0-9, KHÔNG PHẢI dấu trừ... rồi đập nát nó thành chuỗi rỗng""cho tao!".Giải mã cơ học:
2. FUNCTION (HÀM) — Nhà Máy Đóng Gói Logic
Hàm là một cái hộp đen. Bạn ném nguyên liệu (Tham số) vào, nó chạy rầm rầm bên trong, rồi nhả ra thành phẩm (Return).
2.1. Tham số mặc định (Default Parameters)
Bảo hiểm chống lỗi khi người dùng quên truyền dữ liệu.
Cơ học: Gán trực tiếp dấu
=ngay trên khai báo tham số.Ứng dụng (Bài tập
formatPrice): Đề bài yêu cầu: Nếu không truyền currency → mặc định "VND".
function formatPrice(price, currency = "VND") {
// Nếu lúc gọi hàm không truyền "USD", currency sẽ tự động chốt là "VND"
}2.2. Return — Phanh Khẩn Cấp & Bàn Giao Hàng
Cỗ máy Function chỉ thực sự "trả hàng" cho bạn khi nó đụng chữ
return.Đặc tính sống còn:
returnlà một cái phanh khẩn cấp. Hàm đang chạy mà gặpreturnthì nó lập tức văng ra ngoài, mọi dòng code phía dướireturnđều biến thành rác (dead code), vĩnh viễn không được chạy.
2.3. Arrow Function (Hàm Mũi Tên =>)
Cú pháp rút gọn hiện đại của ES6. Thay vì viết dài dòng:
const add = function(a, b) {
return a + b;
};Viết kiểu Pro:
const add = (a, b) => a + b;(Nếu hàm chỉ có 1 dòng thực thi duy nhất, bạn được quyền vứt luôn dấu {} và chữ return. Máy tự hiểu là tính xong thì trả về luôn).
3. NUMBER (SỐ HỌC) — Những Cú Lừa Kinh Điển
Dù bài tập Buổi 17 chưa đụng sâu vào số, nhưng file Note của bạn đã đề cập, và đây là thứ giết chết các đoạn script tính tiền.
3.1. Cái bẫy của dấu +
JS rất ba phải. Dấu + vừa dùng để cộng toán học, vừa dùng để nối chuỗi.
Quy luật: Cứ hễ trong phép cộng có sự xuất hiện của 1 cái Chuỗi, JS sẽ lập tức phản bội Toán học, ép tất cả thành Chuỗi và NỐI LẠI với nhau.
10 + 20➔30"10" + 20➔"1020"(Sập logic tính tổng giỏ hàng ngay lập tức!).
3.2. Cứu cánh Ép kiểu (Type Casting)
Dữ liệu cào từ Web (DOM) xuống luôn là Chuỗi. Phải lột mặt nạ nó trước khi tính toán.
Number("1500")➔ Ra số1500.parseInt("100px")➔ Ra số100(Rất hay dùng để bóc tách số từ chuỗi có dính chữ cái ở đuôi).
Bản Thiết Kế (Pseudocode) ráp Bài Tập F8 Buổi 17:
Sử dụng mớ vũ khí vừa note ở trên, bạn thử nhìn lướt qua luồng logic cho 2 bài khó nhất nhé:
Hàm 1: createSlug(text)
Nhận
textvào ➔ Dùng.toLowerCase()ép thành chữ thường toàn bộ.Dùng
.replaceAll(" ", "-")(hoặc.replace(/\s+/g, "-")) để đổi tất cả khoảng trắng thành dấu trừ.Dùng tuyệt chiêu Regex
.replace(/[^a-z0-9\-]/g, "")để thanh trừng mọi ký tự lạ (như!,@,#).returnkết quả ra.
Hàm 2: generateOrderId(productName, quantity)
Lấy
productName➔ Dùng.slice(0, 3)bóc 3 chữ đầu ➔ Dùng tiếp.toUpperCase()ép in hoa. Lưu vào biếnprefix.Lấy
productName.lengthđể đo độ dài chuỗi gốc. Lưu vào biếnlen.Dùng Template Literals (
`ORD-${prefix}-${quantity}-${len}`) để ráp nối tất cả lại thành 1 chuỗi hoàn chỉnh.returncái chuỗi đó ra.
Bộ note này đã đủ "đô" để bạn ném vào hệ thống Hub và làm tư liệu thi triển code cho toàn bộ Assignment Buổi 17 chưa? Cứ nhìn vào sườn Pseudocode kia, tự tay gõ lại bằng JS xem cỗ máy nó vận hành mượt mà thế nào nhé! Tắc ở đâu chúng ta lại gỡ ở đó.
BỔ SUNG LÝ THUYẾT: 3 QUẢ MÌN NGẦM CẦN TRÁNH
1. Cạm bẫy Hoisting: Khai báo hàm thường vs Biểu thức hàm
Trong bài học có nhấn mạnh sự khác biệt giữa Function Declaration (Hàm thường) và Function Expression / Arrow Function (Hàm mũi tên).
Cơ học ngầm: Hàm thường sẽ được tự động "kéo lên đầu" (Hoisting) khi chạy. Bạn gọi hàm ở dòng 1, định nghĩa hàm ở dòng 10 vẫn chạy bình thường. Nhưng Hàm mũi tên lưu vào biến thì KHÔNG. Bạn bắt buộc phải định nghĩa trước rồi mới được gọi.
Hành vi thực tế: Nếu viết script tracking sự kiện (ví dụ: tracking nút Add to Cart), nếu dùng Arrow Function mà đặt vị trí gọi hàm sai trật tự, script sẽ chết đứng lập tức.
2. Cạm bẫy this trong Arrow Function (Cực kỳ nguy hiểm khi làm WP)
Cơ học ngầm: Arrow function không có từ khóa
thisriêng của nó. Nó sẽ lấythiscủa môi trường bao quanh nó.Hành vi thực tế: Khi bạn viết code tùy biến cho WordPress/Elementor, hoặc cấu hình các object chứa thông tin sản phẩm (như cấu hình GTM DataLayer), nếu dùng Arrow function làm phương thức của Object,
this.namesẽ trả vềundefined(vì nó trỏ ra đối tượngwindowtoàn cục chứ không trỏ vào sản phẩm).
Quy tắc bỏ túi: Làm phương thức cho Object hoặc viết hàm xử lý sự kiện click trên giao diện web ➔ Cấm dùng Arrow Function.
3. Truyền giá trị (Value) vs Truyền tham chiếu (Reference)
Kiểu nguyên thủy (String, Number): Khi truyền vào hàm, máy tạo ra một bản sao. Thao tác biến đổi trong hàm không làm thay đổi biến gốc bên ngoài.
Kiểu Object, Array (Bài tập
buildProductUrl): Khi truyền một Object sản phẩm vào hàm, máy tính sẽ truyền địa chỉ ô nhớ gốc.Hành vi thực tế: Nếu bên trong hàm bạn vô tình ghi đè
product.name = "Đã sửa", thì cái Object sản phẩm gốc nằm bên ngoài hàm cũng bị sửa đổi theo. Đây là nguyên nhân gây ra 80% bug dữ liệu phập phù.
BỔ SUNG BẢN THIẾT KẾ CHO 2 HÀM CÒN LẠI CỦA BÀI TẬP
Để hoàn thành 100%
Hàm 3: formatPrice(price, currency = "VND")
- Thiết lập tham số mặc định cho
currency = "VND"ngay trên đầu hàm để phòng hờ trường hợp khách quên truyền. - Dùng cấu trúc rẽ nhánh
if / elseđể bắt đúng bệnh: if (currency === "VND"): Bạn có thể dùng công thức bùa chú có sẵn trong bài học:new Intl.NumberFormat('vi-VN', { style: 'currency', currency: 'VND' }).format(price)để tự động đẻ ra dấu chấm phân tách hàng nghìn và ký hiệu₫.else if (currency === "USD"): Tương tự, đổi locale thành'en-US'và currency thành'USD'.returnchuỗi tiền tệ đã được định dạng xịn sò ra ngoài.
Hàm 4: buildProductUrl(baseUrl, product)
- Tạo ra một biến
slugbằng cách lấy tên sản phẩmproduct.nameném vào cái hàmcreateSlug()mà bạn đã viết ở Hàm 1. (Kỹ thuật tái sử dụng hàm). - Sử dụng Template Literals với dấu backtick ` để ráp nối cơ học:
return `${baseUrl}/${product.category}/${slug}?id=${product.id}`;Như vậy là bộ cẩm nang Buổi 17 của bạn đã khép kín hoàn toàn từ thực hành cho tới bản chất ngầm dưới bộ nhớ. Hãy lưu lại toàn bộ phần bổ sung này vào Hub.
Bây giờ chúng ta đã sẵn sàng để dồn toàn lực, gia tốc hiệu suất nhảy sang cày cuốc lý thuyết cốt lõi của Buổi 18 (Number nâng cao và bộ lọc Reduce) chưa?