10 Thủ thuật JavaScript mà bạn ước rằng giá như biết được sớm hơn (P1)
Thực tế là với tư cách là lập trình viên, ắt hẳn các bạn sẽ luôn tìm đủ mọi cách để tối giản hóa khối lượng công việc và tiết kiệm cả đống thời gian cho việc viết code hàng ngày.
Tất nhiên chả ai lại muốn đánh vật với những đoạn mã vừa dài vừa phức tạp trong khi bên ngoài kia có khá nhiều mẹo hữu ích để đơn giản hóa công việc cho bạn.
Ở bài viết này tôi sẽ chia sẻ 10 thủ thuật vô cùng hữu ích khi dùng JavaScript, một số có sẵn, một số phải tùy chỉnh nhưng chắc chắn sẽ làm bạn phải kinh ngạc và trầm trồ đấy. Hãy cùng bắt đầu nhé!!!
1. Mẹo sử dụng chuỗi tùy chọn - Tạm biệt các lỗi dữ liệu nhé
Vấn đề ở đây: Bạn đang cố gắng truy cập một thuộc tính sâu bên trong một đối tượng, nhưng bạn không chắc chắn rằng liệu tất cả các thuộc tính trong chuỗi có tồn tại hay không. Điều này có thể dẫn đến những lỗi đáng sợ như là "Không thể đọc được các thuộc tính của undefined". VD:
const user = {
// address: { street: "123 Main St" }
};
let street = user.address.street;
console.log(street); // Uncaught TypeError: Cannot read properties of undefined (reading 'street')
Giải pháp cũ chúng ta thường dùng:: Bạn sẽ phải viết một loạt các câu lệnh if lồng vào nhau để kiểm tra xem từng thuộc tính có tồn tại hay không trước khi thử truy cập vào thuộc tính đó. VD:
const user = {
// address: { street: "123 Main St" }
};
// The old, painful way:
let street = user && user.address && user.address.street;
console.log(street); // undefined
Giải pháp mới mẻ mà tôi khuyến khích: Sử dụng chuỗi tùy chọn để giải quyết vấn đề. Với ?., biểu thức sẽ chuyển sang undefined nếu thiếu thuộc tính, nhờ đó giúp ngăn ngừa lỗi có thể xảy ra.
const user = {
// address: { street: "123 Main St" }
};
// The elegant, modern way:
let street = user?.address?.street;
console.log(street); // undefined:
Với chuỗi tùy chọn (?.), nếu bất kỳ thuộc tính nào trong chuỗi là null hoặc không xác định, biểu thức sẽ bị trục trặc nhỏ và chỉ trả về undefined thay vì ném ra TypeError đáng sợ. Không còn những câu lệnh if rườm rà làm lộn xộn các đoạn mã của bạn nữa!
Ứng dụng thực tế: Hãy tưởng tượng bạn đang lấy dữ liệu từ API và cấu trúc phản hồi có thể thay đổi. Thay vì viết nhiều kiểm tra lồng nhau, sử dụng chuỗi tùy chọn sẽ cung cấp một cách rõ ràng và ngắn gọn để truy cập dữ liệu có thể có hoặc không có.
2. Mẹo sử dụng Nullish - Giúp các giá trị mặc định trở nên tốt hơn
Vấn đề ở đây: Bạn muốn gán giá trị mặc định cho một biến nếu biến đó là null hoặc không xác định, nhưng bạn không muốn vô tình ghi đè các giá trị sai có thể hợp lệ trong đoạn mã của bạn, như 0 hoặc chuỗi rỗng.
Giải pháp cũ thường dùng trước đây: Sử dụng toán tử logic OR (||) để đặt mặc định có thể dẫn đến những hậu quả không mong muốn về sau này. VD:
const user = { name: 0 };
// The old way (potentially problematic):
let postCount = user.name || "No posts yet!";
console.log(postCount); // Outputs "No posts yet!", even though 0 might be a valid post count.
Giải pháp tốt nhất nên làm: Sử dụng toán tử hợp nhất Nullish (??) để cứu vãn tình hình. Nó chỉ cung cấp giá trị mặc định nếu toán hạng bên trái là null hoặc không xác định. VD:
const user = { name: 0 };
// The new, improved way:
let postCount = user.name ?? "No posts yet!";
console.log(postCount); // Outputs 0, respecting the actual value of user.name
Lệnh ?? đáng tin cậy này chỉ can thiệp nếu toán hạng bên trái là null hoặc không xác định, đảm bảo giá trị mặc định chỉ được sử dụng khi cần thiết.
Ứng dụng thực tế: Hãy tưởng tượng một hồ sơ người dùng trong đó 0 là đầu vào hợp lệ cho "số bài đăng". Sử dụng || để đặt mặc định sẽ thay thế 0 bằng mặc định một cách không chính xác. Toán tử ?? tránh được lỗi này, tôn trọng ý nghĩa thực sự của 0 trong ngữ cảnh này.
3. Mẹo sử dụng Object.freeze() - làm cho nó không thể thay đổi
Vấn đề ở đây: Bạn có một đối tượng và bạn muốn đảm bảo rằng không có thuộc tính nào của đối tượng có thể bị thay đổi một cách vô tình sau khi đối tượng được tạo. Điều này đặc biệt quan trọng đối với các đối tượng cấu hình hoặc dữ liệu cần phải giữ nguyên. VD:
const colors = {
primary: "blue",
secondary: "green"
};
colors.primary = "red"; // Accidental modification is too easy!
console.log(colors.primary); // Outputs "red" - the object was modified
Giải pháp nên làm: Sử dụng hàm Object.freeze() để làm cho đối tượng của bạn trở nên "bất khả xâm phạm". Nó sẽ ngăn chặn mọi sửa đổi thêm đối với các thuộc tính của đối tượng.
const colors = {
primary: "blue",
secondary: "green"
};
Object.freeze(colors);
colors.primary = "red"; // This will silently fail
console.log(colors.primary); // Still outputs "blue"
Object.freeze() lấy một đối tượng và làm cho nó không thể thay đổi. Bất kỳ nỗ lực nào để thay đổi thuộc tính của nó sẽ bị bỏ qua một cách thầm lặng. Giống như việc đặt đối tượng của bạn vào tủ trưng bày – bạn có thể nhìn, nhưng không thể chạm vào. Rất dễ hiểu phải không nào!!!
Ứng dụng thực tế: Hãy tưởng tượng bạn có các thiết lập cấu hình được lưu trữ trong một đối tượng. Sử dụng Object.freeze() sẽ giúp đảm bảo các thiết lập này không đổi trong suốt ứng dụng của bạn, ngăn ngừa các sửa đổi vô tình có thể dẫn đến hành vi không mong muốn.
4. Mẹo phân tách mảng - Giúp giải nén dễ hơn
Vấn đề ở đây: Bạn cần trích xuất các giá trị cụ thể từ một mảng và gán chúng cho các biến riêng lẻ. Truy cập mảng truyền thống bằng chỉ số có thể hơi khó khăn, đặc biệt là đối với các mảng dài hơn.
Giải pháp cũ thường làm: Bạn sẽ phải truy cập các phần tử theo chỉ mục, điều này khó đọc và dễ xảy ra lỗi hơn, đặc biệt là khi mảng ngày càng lớn. VD:
const rgb = [255, 128, 0];
const red = rgb[0];
const green = rgb[1];
const blue = rgb[2];
console.log(red, green, blue); // 255 128 0
Giải pháp nên làm: Hãy phân tách cấu trúc mảng được cung cấp một cách tinh tế và dễ đọc để "biến" các phần tử mảng thành các biến riêng biệt.
const rgb = [255, 128, 0];
const [red, green, blue] = rgb;
console.log(red, green, blue); // 255 128 0
Bằng cách sử dụng dấu ngoặc vuông [] ở bên trái của phép gán, chúng ta tạo ra một mẫu phản ánh cấu trúc của mảng. Sau đó, JavaScript sẽ gán gọn gàng các giá trị tương ứng từ mảng cho các biến. Vô cùng gọn gàng phải không nào!!!
Ứng dụng thực tế: Hãy tưởng tượng bạn có một mảng biểu diễn thông tin của người dùng: [tên, tuổi, thành phố]. Với giải cấu trúc, bạn có thể dễ dàng trích xuất các giá trị này thành các biến riêng biệt để có mã dễ đọc và dễ bảo trì hơn.
5. Mẹo sử dụng tham số mặc định - Không còn đau đầu về các giá trị không xác định
Vấn đề ở đây: Bạn đang viết một hàm và muốn cung cấp các giá trị mặc định cho các tham số trong trường hợp người gọi không cung cấp chúng.
Giải pháp cũ trước đây: Bạn sẽ phải kiểm tra xem các đối số có chưa được xác định trong thân hàm hay không và gán các giá trị mặc định theo cách thủ công. VD:
function greet(name, message) {
const userName = name || "Stranger";
const greeting = message || "Hello there!";
console.log(`${greeting}, ${userName}!`);
}
greet(); // Hello there!, Stranger!
greet("Alice"); // Hello there!, Alice!
greet("Bob", "Good morning"); // Good morning, Bob!
Giải pháp mới nên làm: Sử dụng các tham số mặc định cho phép bạn chỉ định giá trị mặc định cho tham số hàm trực tiếp trong định nghĩa hàm.
Bằng cách gán giá trị cho các tham số trong chữ ký hàm (name = "Stranger"), chúng ta yêu cầu JavaScript sử dụng các giá trị đó nếu các đối số tương ứng không được cung cấp khi hàm được gọi.
Ứng dụng thực tế: Hãy xem xét một hàm tính diện tích của một hình chữ nhật. Bạn có thể đặt giá trị mặc định cho chiều rộng và chiều cao là 1, do đó nếu hàm được gọi mà không có đối số, nó sẽ trả về diện tích của một hình vuông đơn vị.
Trên đây là phần 1 của chuỗi bài viết về thủ thuật khi sử dụng JavaScript, mời bạn đọc tiếp phần 2 tại đây: https://viblo.asia/p/10-thu-thuat-javascript-ma-ban-uoc-rang-gia-nhu-biet-duoc-som-hon-p2-EvbLbaKZJnk
All rights reserved