أفضل الممارسات للحلقات التكرارية في TypeScript
تشرح هذه المقالة أفضل الممارسات لاستخدام الحلقات التكرارية في TypeScript۔
YouTube Video
أفضل الممارسات للحلقات التكرارية في TypeScript
عبارات for
هي بنية أساسية وقوية لتنفيذ العمليات المتكررة.۔ في TypeScript، الاستفادة من سلامة الأنواع وكتابة الكود مع مراعاة قابلية القراءة والصيانة تتيح لك كتابة كود فعّال وبه أخطاء أقل.۔
اختيار النوع المناسب من الحلقات التكرارية
تقدم TypeScript عدة تراكيب للحلقات التكرارية، ولكل منها استخدامات مناسبة لحالات مختلفة۔ اختيار الحلقة التكرارية المناسبة أمر ضروري لوضوح الكود والأداء۔
الحلقة التكرارية for
العادية
1for (let i = 0; i < 10; i++) {
2 console.log(i);
3}
الحلقة القياسية for
مثالية عندما تحتاج إلى التحكم الدقيق في مؤشر التكرار۔
أفضل الممارسات
1const maxIterations = 10;
2for (let i = 0; i < maxIterations; i++) {
3 console.log(i);
4}
عند كتابة عبارات for
، يمكن أن يساعدك مراعاة النقاط التالية في كتابة كود أكثر أمانًا وقابلية للقراءة.۔
- استخدم
let
لمتغيرات المؤشر- استخدام
let
بدلاً منvar
يحد من النطاق إلى الكتلة، مما يمنع سلوكًا غير مقصود.۔
- استخدام
- استخدام الثوابت وأسماء المتغيرات الوصفية لجعل حدود الحلقة واضحة
- تجنب الأرقام السحرية واستخدام أسماء متغيرات ذات معنى يحسن من قابلية القراءة.۔
الحلقة التكرارية for...of
1const array = [1, 2, 3];
2for (let value of array) {
3 console.log(value);
4}
تعد حلقة for...of
مناسبة للتكرار على الكائنات القابلة للتكرار مثل الصفائف والسلاسل النصية۔
أفضل الممارسات
1const array = [1, 2, 3];
2for (const value of array) {
3 console.log(value);
4}
عند كتابة حلقات for...of
، يمكن أن يساعدك مراعاة النقاط التالية في كتابة كود أكثر أمانًا.۔
- استخدم
const
لمتغيرات الحلقة- إذا لم يتم تعديل القيم داخل الحلقة، فإن استخدام
const
يساعد في منع إعادة التعيين العرضية.۔
- إذا لم يتم تعديل القيم داخل الحلقة، فإن استخدام
الحلقة التكرارية for...in
1const obj = { a: 1, b: 2, c: 3 };
2for (const key in obj) {
3 console.log(`${key}: ${obj[key]}`);
4}
تتكرر حلقة for...in
على الخصائص القابلة للتعداد للكائن۔
أفضل الممارسات
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}
عند كتابة حلقة for...in
، يمكنك مراعاة النقاط التالية۔
- تصفية الخصائص
- إذا كنت بحاجة لتجنب الخصائص الموروثة، يمكنك استخدام
hasOwnProperty
.۔
- إذا كنت بحاجة لتجنب الخصائص الموروثة، يمكنك استخدام
- لا تستخدم
for...in
مع المصفوفات تجنب استخدامfor...in
مع المصفوفات۔ قد يتم التكرار عبر جميع الخصائص القابلة للتعداد، بما في ذلك الخصائص التي ليست مؤشرات للمصفوفة۔
طريقة forEach
1const array = [1, 2, 3];
2array.forEach((value, index) => {
3 console.log(`Index: ${index}, Value: ${value}`);
4});
عند التكرار عبر الصفائف، تعتبر forEach
مختصرة وتلغي الحاجة لإدارة المؤشرات۔
أفضل الممارسات
عند استخدام طريقة forEach
، يمكنك مراعاة النقاط التالية۔
- استخدم الدوال السهمية
- استخدم الدوال السهمية المختصرة لتحسين الوضوح۔
- تجنب المقاطعات
forEach
لا تدعمbreak
أوcontinue
۔ استخدم الحلقاتfor...of
أوfor
عندما يكون ذلك ضروريًا:۔
أمان النوع ومنع الأخطاء
من خلال الاستفادة من نظام النوع في TypeScript، يمكنك منع أخطاء وقت التشغيل أثناء التكرار:۔
حدد أنواع صارمة لمتغيرات الحلقة
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});
من خلال تحديد الأنواع بشكل صريح لمتغيرات الحلقة، يمكنك اكتشاف عدم التوافق في الأنواع مبكرًا.۔
تجنب الاستخدام الضمني لـ any
1{
2 "compilerOptions": {
3 "noImplicitAny": true
4 }
5}
أيضًا، من خلال تمكين noImplicitAny
في الملف tsconfig.json
، يمكنك منع المتغيرات التي ليس لها أنواع واضحة من أن تُعيَّن لها النوع any
بشكل ضمني.۔
استخدم ReadonlyArray
عند الحاجة
1const numbers: ReadonlyArray<number> = [1, 2, 3];
2for (const value of numbers) {
3 console.log(value);
4}
إذا كنت تقوم بتكرار مصفوفة لا يجب تعديلها، يمكنك استخدام ReadonlyArray
۔
اعتبارات الأداء
تعد الكفاءة أمرًا بالغ الأهمية للحلقات التي تعالج مجموعات بيانات كبيرة أو الحلقات التي تُنفذ بشكل متكرر:۔
اختر الطريقة المثلى لتنفيذ الحلقة.
هناك طرق متنوعة لتنفيذ الحلقات، ولكل منها اختلافات في قابلية القراءة وكفاءة التنفيذ۔
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');
تختلف الكفاءة اعتمادًا على بيئة التنفيذ، ولكن على سبيل المثال، عند تشغيل حلقة مليون مرة، يمكن أن يصبح الفارق ملحوظًا للغاية۔ اختر الطريقة المثلى للحلقة مع مراعاة القابلية للصيانة والأداء۔
استخدم طرق التكرار الأصلية
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]
يمكن أن تكون الطرق مثل map
وfilter
أكثر وضوحًا في بعض الحالات.۔
يفضل استخدام for...of
لتحسين قابلية القراءة
يجب إعطاء الأولوية للأداء في حالات محدودة فقط؛ فكتابة كود قابل للقراءة هو الأهم عمومًا.۔ على سبيل المثال، يمكن أن يؤدي إعطاء الأولوية لـ for...of
إلى تحسين قابلية القراءة.۔
1const fruits = ["apple", "banana", "cherry"];
2
3for (let i = 0; i < fruits.length; i++) {
4 console.log(`${i}: ${fruits[i]}`);
5}
أفضل الممارسات
1const fruits = ["apple", "banana", "cherry"];
2
3for (const [index, fruit] of fruits.entries()) {
4 console.log(`${index}: ${fruit}`);
5}
من خلال إعطاء الأولوية لحلقات for...of
، يمكنك كتابة كود أكثر قابلية للقراءة ومقاومة للأخطاء.۔ كما هو موضح في هذا المثال، إذا كنت بحاجة أيضًا إلى مؤشرات المصفوفة، فإن الجمع بين entries()
وfor...of
يكون فعالًا.۔
تجنب العثرات الشائعة
تعديل المجموعات أثناء التكرار
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);
يمكن أن يؤدي تعديل مصفوفة أثناء التكرار إلى سلوك غير متوقع:۔ استخدم نسخة إذا لزم الأمر۔
ضع في اعتبارك الحالات الحدودية
1const array: number[] = [];
2for (const value of array) {
3 console.log(value); // No output, but no errors
4}
يعمل هذا الكود بشكل جيد، لكن إذا كنت بحاجة إلى التعامل مع المصفوفات الفارغة، يمكنك تحسينه على النحو التالي۔
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}
أخذ الحالات الحدودية في الاعتبار يمكن أن يساعد في منع الأخطاء في الكود اللاحق۔
الخاتمة
لإتقان تعليمات for
في TypeScript، من الضروري فهم تركيبات التكرار المختلفة، الالتزام بممارسات آمنة للأنواع، وتحسين الأداء.۔ تساعدك هذه الممارسات المثلى على كتابة كود أنظف وأكثر موثوقية وأسهل في الصيانة۔
يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔