Thực hành tốt nhất cho vòng lặp for trong TypeScript

Thực hành tốt nhất cho vòng lặp for trong TypeScript

Bài viết này giải thích những thực hành tốt nhất khi sử dụng vòng lặp for trong TypeScript.

YouTube Video

Thực hành tốt nhất cho vòng lặp for trong TypeScript

Câu lệnh for là một cú pháp cơ bản và mạnh mẽ để thực hiện các thao tác lặp đi lặp lại. Trong TypeScript, tận dụng tính an toàn kiểu và viết mã với mục tiêu dễ đọc và dễ bảo trì giúp bạn viết mã hiệu quả với ít lỗi hơn.

Chọn loại vòng lặp phù hợp

TypeScript cung cấp nhiều cấu trúc vòng lặp, mỗi loại phù hợp với các trường hợp sử dụng khác nhau. Việc chọn vòng lặp phù hợp là rất quan trọng cho sự rõ ràng của mã và hiệu suất.

Vòng lặp for chuẩn

1for (let i = 0; i < 10; i++) {
2    console.log(i);
3}

Vòng lặp for tiêu chuẩn rất lý tưởng khi bạn cần kiểm soát chính xác chỉ số vòng lặp.

Các phương pháp tốt nhất
1const maxIterations = 10;
2for (let i = 0; i < maxIterations; i++) {
3    console.log(i);
4}

Khi viết các câu lệnh for, việc lưu ý các điểm sau có thể giúp bạn viết mã an toàn hơn và dễ đọc hơn.

  • Sử dụng let cho các biến chỉ số
    • Sử dụng let thay vì var giới hạn phạm vi trong khối, ngăn chặn hành vi không mong muốn.
  • Sử dụng hằng số và tên biến mô tả để làm rõ ranh giới vòng lặp
    • Tránh sử dụng các số vô nghĩa (magic numbers) và sử dụng tên biến có ý nghĩa sẽ cải thiện khả năng đọc mã.

Vòng lặp for...of

1const array = [1, 2, 3];
2for (let value of array) {
3    console.log(value);
4}

Vòng lặp for...of phù hợp để duyệt qua các đối tượng có thể lặp lại như mảng và chuỗi.

Các phương pháp tốt nhất
1const array = [1, 2, 3];
2for (const value of array) {
3    console.log(value);
4}

Khi viết vòng lặp for...of, chú ý đến các điểm sau có thể giúp bạn viết mã an toàn hơn.

  • Sử dụng const cho các biến trong vòng lặp
    • Nếu các giá trị không bị thay đổi trong vòng lặp, sử dụng const sẽ giúp ngăn chặn việc gán lại không mong muốn.

Vòng lặp for...in

1const obj = { a: 1, b: 2, c: 3 };
2for (const key in obj) {
3    console.log(`${key}: ${obj[key]}`);
4}

Vòng lặp for...in duyệt qua các thuộc tính có thể liệt kê của một đối tượng.

Các phương pháp tốt nhất
1const obj = { a: 1, b: 2, c: 3 };
2for (const key in obj) {
3    if (obj.hasOwnProperty(key)) {
4        console.log(`${key}: ${obj[key]}`);
5    }
6}

Khi viết một vòng lặp for...in, bạn có thể cân nhắc các điểm sau.

  • Lọc các thuộc tính
    • Nếu bạn cần tránh các thuộc tính được kế thừa, bạn có thể sử dụng hasOwnProperty.
  • Không sử dụng for...in với mảng Tránh sử dụng for...in với mảng. Nó có thể lặp qua tất cả các thuộc tính có thể liệt kê, bao gồm cả những thuộc tính không phải là chỉ số của mảng.

Phương thức forEach

1const array = [1, 2, 3];
2array.forEach((value, index) => {
3    console.log(`Index: ${index}, Value: ${value}`);
4});

Khi duyệt qua mảng, forEach ngắn gọn và loại bỏ nhu cầu quản lý chỉ số.

Các phương pháp tốt nhất

Khi sử dụng phương thức forEach, bạn có thể cân nhắc các điểm sau.

  • Sử dụng hàm mũi tên (arrow functions)
    • Sử dụng các hàm mũi tên ngắn gọn để cải thiện khả năng đọc.
  • Tránh các gián đoạn
    • forEach không hỗ trợ break hoặc continue. Sử dụng vòng lặp for...of hoặc for khi cần thiết:.

An toàn kiểu dữ liệu và phòng tránh lỗi

Bằng cách sử dụng hệ thống kiểu của TypeScript, bạn có thể ngăn chặn lỗi xảy ra khi thực hiện vòng lặp:.

Định nghĩa kiểu dữ liệu chặt chẽ cho biến vòng lặp

1const items = [1, 2, 3];
2items.forEach(item => {
3    console.log(item * 2);
4});
1const items: number[] = [1, 2, 3];
2items.forEach((item: number) => {
3    console.log(item * 2);
4});

Bằng cách chỉ rõ kiểu cho các biến trong vòng lặp, bạn có thể phát hiện sớm các lỗi không khớp kiểu.

Tránh kiểu dữ liệu any ngầm định

1{
2  "compilerOptions": {
3    "noImplicitAny": true
4  }
5}

Ngoài ra, bằng cách bật noImplicitAny trong tsconfig.json, bạn có thể ngăn các biến không có kiểu rõ ràng bị gán ngầm định kiểu any.

Sử dụng ReadonlyArray khi cần thiết

1const numbers: ReadonlyArray<number> = [1, 2, 3];
2for (const value of numbers) {
3    console.log(value);
4}

Nếu bạn đang lặp qua một mảng không nên thay đổi, bạn có thể sử dụng ReadonlyArray.

Cân nhắc về hiệu suất

Hiệu suất rất quan trọng đối với các vòng lặp xử lý bộ dữ liệu lớn hoặc được thực hiện thường xuyên:.

Chọn phương pháp triển khai vòng lặp tối ưu nhất.

Có nhiều cách khác nhau để triển khai vòng lặp, mỗi cách đều có sự khác biệt về khả năng đọc mã và hiệu suất thực thi.

 1// Prepare input data (an array from 1 to 1000000)
 2const input: number[] = Array.from({ length: 1000000 }, (_, i) => i + 1);
 3
 4// --- for ---
 5console.time('for loop');
 6const squaresFor: number[] = [];
 7for (let i = 0; i < input.length; i++) {
 8    squaresFor.push(input[i] * input[i]);
 9}
10console.timeEnd('for loop');
11
12// --- while ---
13console.time('while loop');
14const squaresWhile: number[] = [];
15let i: number = 0;
16while (i < input.length) {
17    squaresWhile.push(input[i] * input[i]);
18    i++;
19}
20console.timeEnd('while loop');
21
22// --- for-of ---
23console.time('for-of loop');
24const squaresForOf: number[] = [];
25for (const num of input) {
26    squaresForOf.push(num * num);
27}
28console.timeEnd('for-of loop');
29
30// --- forEach ---
31console.time('forEach loop');
32const squaresForEach: number[] = [];
33input.forEach((num: number): void => {
34    squaresForEach.push(num * num);
35});
36console.timeEnd('forEach loop');
37
38// --- map ---
39console.time('map');
40const squaresMap: number[] = input.map((value: number): number => value * value);
41console.timeEnd('map');

Hiệu suất thay đổi tùy vào môi trường thực thi, nhưng chẳng hạn, khi chạy một vòng lặp đến một triệu lần, sự khác biệt có thể trở nên dễ nhận thấy. Hãy chọn phương pháp vòng lặp tối ưu, cân nhắc giữa khả năng bảo trì và hiệu suất.

Sử dụng các phương pháp lặp tích hợp

 1const squares = [1, 2, 3].map(value => value * value);
 2console.log(squares);
 3
 4const numbers = [1, 2, 3, 4, 5, 6];
 5const evenNumbers = numbers.filter(value => value % 2 === 0);
 6console.log(evenNumbers); // [2, 4, 6]
 7
 8const squaredEvens = numbers
 9    .filter(value => value % 2 === 0) // Keep only even numbers
10    .map(value => value * value);     // Square the remaining values
11
12console.log(squaredEvens); // [4, 16, 36]

Các phương thức như mapfilter có thể dễ đọc hơn trong một số trường hợp.

Ưu tiên sử dụng for...of để tăng khả năng đọc

Hiệu suất chỉ nên được ưu tiên trong một số trường hợp giới hạn; viết mã dễ đọc thường quan trọng hơn. Ví dụ, ưu tiên sử dụng for...of có thể cải thiện khả năng đọc mã.

1const fruits = ["apple", "banana", "cherry"];
2
3for (let i = 0; i < fruits.length; i++) {
4    console.log(`${i}: ${fruits[i]}`);
5}
Các phương pháp tốt nhất
1const fruits = ["apple", "banana", "cherry"];
2
3for (const [index, fruit] of fruits.entries()) {
4    console.log(`${index}: ${fruit}`);
5}

Bằng cách ưu tiên các vòng lặp for...of, bạn có thể viết mã dễ đọc hơn và ít lỗi hơn. Như được minh họa trong ví dụ này, nếu bạn cũng cần chỉ số mảng, việc kết hợp entries() với for...of là hiệu quả.

Tránh các lỗi thường gặp

Thay đổi tập hợp trong quá trình lặp

1const array = [1, 2, 3];
2for (const value of [...array]) {
3    if (value === 2) {
4        array.push(4); // Avoid this!
5    }
6}
7console.log(array);

Việc thay đổi một mảng trong quá trình lặp có thể dẫn đến hành vi không mong muốn:. Sử dụng một bản sao nếu cần thiết.

Hãy xem xét các trường hợp đặc biệt

1const array: number[] = [];
2for (const value of array) {
3    console.log(value); // No output, but no errors
4}

Đoạn mã này hoạt động tốt, nhưng nếu bạn cần xử lý các mảng rỗng, bạn có thể cải thiện như sau.

1const array: number[] = [];
2if (array.length === 0) {
3    console.log("The array is empty.");
4} else {
5    for (const value of array) {
6        console.log(value);
7    }
8}

Xem xét các trường hợp đặc biệt có thể giúp ngăn ngừa lỗi trong các đoạn mã sau.

Kết luận

Để thành thạo câu lệnh for trong TypeScript, điều quan trọng là hiểu các cấu trúc vòng lặp khác nhau, tuân thủ các thực tiễn an toàn kiểu và tối ưu hóa hiệu suất. Những phương pháp tối ưu này giúp bạn viết mã sạch hơn, đáng tin cậy hơn và dễ bảo trì hơn.

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.

YouTube Video