Các phương pháp hay nhất cho việc lặp lại trong JavaScript
Bài viết này giải thích các phương pháp hay nhất cho việc lặp lại trong JavaScript.
YouTube Video
Các phương pháp hay nhất cho việc lặp lại trong JavaScript
Trong JavaScript, việc sử dụng vòng lặp for để lặp lại là phổ biến. Tại đây, chúng ta sẽ cung cấp giải thích chi tiết về các phương pháp hay nhất trong việc sử dụng vòng lặp for để viết mã hiệu quả và dễ đọc.
Chọn cấu trúc vòng lặp phù hợp
JavaScript cung cấp nhiều cấu trúc vòng lặp, mỗi loại phù hợp với mục đích khác nhau.
1// Example of a for loop
2for (let i = 0; i < 5; i++) {
3 console.log(i);
4}
5
6// Example of a for...of loop
7const array = [10, 20, 30];
8for (const value of array) {
9 console.log(value);
10}
11
12// Example of a for...in loop
13const obj = { a: 1, b: 2, c: 3 };
14for (const key in obj) {
15 console.log(`${key}: ${obj[key]}`);
16}
17
18// Example of a while loop
19let count = 0;
20while (count < 5) {
21 console.log(count);
22 count++;
23}- Câu lệnh
forphù hợp khi số lần lặp được xác định trước. - Câu lệnh
for...ofphù hợp để xử lý ngắn gọn các mảng và đối tượng có thể duyệt. - Câu lệnh
for...inđược sử dụng để duyệt qua các thuộc tính của đối tượng. Tuy nhiên, nó không phù hợp cho mảng. - Câu lệnh
whilevà câu lệnhdo...whileđược sử dụng để điều khiển vòng lặp dựa trên các điều kiện.
Sử dụng phương thức forEach và câu lệnh for...of
Khi lặp qua một mảng, việc sử dụng câu lệnh for để truy cập chỉ mục là phổ biến, nhưng phương thức forEach hoặc câu lệnh for...of có thể dễ đọc hơn.
1// Using a standard for loop
2const array = ["apple", "banana", "cherry"];
3for (let i = 0; i < array.length; i++) {
4 console.log(array[i]);
5}
6
7// Using forEach
8array.forEach(item => console.log(item));
9
10// Using for...of
11for (const item of array) {
12 console.log(item);
13}- Câu lệnh
forcho phép quản lý chỉ mục rõ ràng khi lặp. - Phương thức
forEachsử dụng hàm gọi lại để xử lý từng phần tử một cách ngắn gọn. - Câu lệnh
for...ofcó tính dễ đọc cao và cho phép truy cập trực tiếp vào từng phần tử trong mảng.
Tối ưu hóa điều kiện vòng lặp
Vì điều kiện vòng lặp được đánh giá nhiều lần, tránh các phép tính không cần thiết có thể cải thiện hiệu suất.
1const names = ["Alice", "Bob", "Charlie"];
2const scores = [85, 92, 78];
3
4// Inefficient example
5for (let i = 0; i < Math.min(names.length, scores.length); i++) {
6 console.log(`${names[i]} scored ${scores[i]}`);
7}
8
9// Efficient example
10for (let i = 0, len = Math.min(names.length, scores.length); i < len; i++) {
11 console.log(`${names[i]} scored ${scores[i]}`);
12}- Như được minh họa trong ví dụ này, lưu trữ kết quả tính toán vào một biến trước sẽ cho phép thực thi vòng lặp hiệu quả hơn.
1const scores = [85, 92, 78];
2let sum = 0;
3let sum2 = 0;
4
5// Inefficient example
6for (let i = 0; i < scores.length; i++) {
7 sum += scores[i];
8}
9console.log(`Total score : ${sum}`);
10
11// Efficient example
12for (let i = scores.length - 1; i >= 0; i--) {
13 sum2 += scores[i];
14}
15console.log(`Total score : ${sum2}`);- Như được minh họa trong ví dụ này, đôi khi việc đảo điều kiện có thể hiệu quả hơn.
Tối ưu hóa xử lý vòng lặp
Vì xử lý vòng lặp được thực hiện lặp đi lặp lại, tránh các tính toán không cần thiết có thể cải thiện hiệu suất.
1const array = ["apple", "banana", "cherry"];
2
3// Inefficient example
4for (let i = 0; i < 100; i++) {
5 const element = document.querySelector("#myElement");
6 element.textContent = `Count: ${i}`;
7}
8
9// Efficient example
10const element = document.querySelector("#myElement");
11for (let i = 0; i < 100; i++) {
12 element.textContent = `Count: ${i}`;
13}- Trong ví dụ này, bằng cách chuyển phương thức
querySelectorra ngoài vòng lặp, các phép tính lặp đi lặp lại không cần thiết được loại bỏ.
Chú ý đến phạm vi biến
Sử dụng let hoặc const để đảm bảo biến bên trong vòng lặp có phạm vi phù hợp. Do var bị giới hạn trong phạm vi hàm, nó có thể gây ra hành vi không mong muốn.
1// Using let
2for (let i = 0; i < 3; i++) {
3 console.log(i);
4}
5
6// Potential issue with var
7for (var i = 0; i < 3; i++) {
8 setTimeout(() => console.log(i), 1000); // 3, 3, 3
9}
10
11// Using let to avoid the issue
12for (let i = 0; i < 3; i++) {
13 setTimeout(() => console.log(i), 1000); // 0, 1, 2
14}varcó phạm vi trong hàm, vì vậy sau vòng lặp giá trị củailà3, và tất cả các hàm được thực thi bởisetTimeoutđều xuất ra3.- Sử dụng
let, giá trịibên trong hàm callback củasetTimeouttham chiếu đến một giá trị mới cho mỗi vòng lặp, vì vậy kết quả0, 1, 2như mong đợi.
Cải thiện tính dễ đọc bằng cách thoát sớm
Để đơn giản hóa xử lý vòng lặp, sử dụng break và continue một cách phù hợp để tăng cường tính dễ đọc.
1// Example using break
2for (let i = 0; i < 10; i++) {
3 if (i === 5) {
4 break; // Exit the loop
5 }
6 console.log(i);
7}
8
9// Example using continue
10for (let i = 0; i < 10; i++) {
11 if (i % 2 === 0) {
12 continue; // Skip to the next iteration
13 }
14 console.log(i);
15}- Sử dụng
breakcho phép bạn kết thúc quá trình xử lý vòng lặp giữa chừng, bỏ qua tất cả các lần lặp tiếp theo. - Sử dụng
continuecho phép bạn bỏ qua quá trình vòng lặp hiện tại và chuyển sang lần lặp kế tiếp.
Tránh lồng ghép sâu
Lồng ghép sâu khiến mã khó đọc hơn, vì vậy hãy cố gắng giữ lồng ghép ở mức nông bằng cách sử dụng trả về sớm hoặc chia chức năng thành các hàm riêng biệt.
1// Deeply nested example
2for (let i = 0; i < 5; i++) {
3 for (let j = 0; j < 5; j++) {
4 if (i + j > 5) {
5 console.log(i, j);
6 }
7 }
8}
9
10// Improved using function decomposition
11function processPairs(i) {
12 for (let j = 0; j < 5; j++) {
13 if (i + j > 5) {
14 console.log(i, j);
15 }
16 }
17}
18
19for (let i = 0; i < 5; i++) {
20 processPairs(i);
21}- Trong ví dụ này, các hàm được sử dụng để giảm độ lồng nhau.
Hãy xem xét xử lý lỗi
Nếu có khả năng xảy ra lỗi trong vòng lặp, hãy triển khai xử lý lỗi thích hợp.
1const data = ["123", "abc", "456", "xyz"];
2
3// Without Error Handling
4for (const item of data) {
5 const result = parseInt(item);
6 console.log(`Parsed value: ${result}`);
7}
8
9// With Error Handling
10for (const item of data) {
11 try {
12 const result = parseInt(item);
13 if (isNaN(result)) {
14 throw new Error(`Invalid number: ${item}`);
15 }
16 console.log(`Parsed value: ${result}`);
17 } catch (error) {
18 console.error(`Error processing item: ${item}. ${error.message}`);
19 }
20}- Trong ví dụ này, xử lý lỗi được thực hiện để xử lý dữ liệu không hợp lệ, phát hiện và báo cáo các vấn đề.
Những điểm cần lưu ý trong xử lý bất đồng bộ
Khi xử lý bất đồng bộ trong vòng lặp, sử dụng async/await có thể tạo ra mã ngắn gọn và dễ hiểu.
1const urls = ["https://example.com/1", "https://example.com/2"];
2
3// Proper handling of asynchronous operations
4async function fetchUrls() {
5 for (const url of urls) {
6 const response = await fetch(url);
7 const data = await response.json();
8 console.log(data);
9 }
10}
11
12fetchUrls();- Mã này lấy bất đồng bộ các URL từ mảng
urlstừng cái một và xử lý kết quả dưới định dạng JSON. Sử dụngasync/awaitgiúp đơn giản hóa các thao tác bất đồng bộ, tuần tự lấy dữ liệu cho từng URL và xuất ra console.
Hiểu sự khác biệt giữa câu lệnh for...of và forEach() trong xử lý bất đồng bộ.
1async function asyncTask(num) {
2 return new Promise(resolve => {
3 setTimeout(() => {
4 console.log(`Task ${num} done`);
5 resolve();
6 }, 100);
7 });
8}
9
10async function runWithForOf() {
11 console.log("Start for...of");
12 for (const num of [1, 2, 3]) {
13 await asyncTask(num);
14 }
15 console.log("End for...of");
16}
17
18async function runWithForEach() {
19 console.log("Start forEach");
20 [1, 2, 3].forEach(async num => {
21 await asyncTask(num);
22 });
23 console.log("End forEach");
24}
25
26async function executeExamples() {
27 await runWithForOf();
28 await runWithForEach();
29}
30
31executeExamples();-
Khi xử lý bất đồng bộ trong các vòng lặp, hãy lưu ý sự khác biệt trong hành vi, như trong ví dụ này, giữa việc sử dụng
for...ofvớiasync/awaitvà sử dụngforEach(). -
Với
for...of, mã sẽ được thực thi tuần tự và dừng lại ởawaitbên trong vòng lặp trước khi tiếp tục đến vòng lặp kế tiếp. Mặt khác,forEach()thực thi các xử lý một cách song song.
Kết luận
for trong JavaScript là một công cụ đơn giản nhưng mạnh mẽ. Bằng cách áp dụng các phương pháp tốt nhất được giới thiệu ở đây, bạn có thể viết mã hiệu quả và dễ đọc. Hãy chú ý chọn cấu trúc vòng lặp phù hợp, quản lý phạm vi, xử lý lỗi, và hướng tới viết mã dễ bảo trì.
Bạn có thể làm theo bài viết trên bằng cách sử dụng Visual Studio Code trên kênh YouTube của chúng tôi. Vui lòng ghé thăm kênh YouTube.