برنامه نویسی ۳۸ بازدید

حلقه foreach‎ در جاوا اسکریپت یکی از متدهای مهمی است که می‌توان آن را برای پیمایش عناصر آرایه‌‌ها به کار برد و عملیات خاصی را روی هر عنصر انجام داد. این متد جاوا اسکریپت دارای ویژگی‌های منحصربه‌فردی است که آن را از سایر روش‌های تکرار روی آرایه‌ها متمایز می‌کند. کار با متد foreach‎ بسیار جالب و قابل‌توجه است و به شدت به خوانایی کدهای ما کمک خواهد کرد.

فهرست مطالب این نوشته

در این مطلب از «مجله فرادرس» می‌خواهیم نحوه استفاده از متد foreach‎ در جاوا اسکریپت و شیوه عملکرد آن را با استفاده از نمونه‌ کدهای واقعی بررسی کنیم. همچنین متد foreach‎ و حلقه for در جاوا اسکریپت را باهم مقایسه خواهیم کرد تا بتوانیم بین آن‌ها بهتر تفاوت قائل شویم و بدانیم چه زمانی باید یکی از آن‌ها را بر دیگری ترجیح دهیم.

سینتکس foreach‎ در جاوا اسکریپت و پارامترهای آن

به عنوان یک پارامتر، foreach‎ تابع callback را می‌پذیرد و آن را برای هر ورودی در آرایه اجرا می‌کند. Callback به بیان ساده تابعی است که باید پس از پایان یافتن تابعی دیگر اجرا شود. این تابع فراخوانی سه آرگومان می‌گیرد و «سینتکس» (syntax) آن به صورت زیر است:

forEach(callback(currentElement, index, arr), thisValue);
پارامترهای forEach در جاوا اسکریپت
  • «عنصر فعلی» ( currentElement ) -  ضروری است.
  • «اندیس فعلی عنصر» ( index ) -  اختیاری است.
  • «آرایه» ( Arr )

در نهایت، پارامتر thisValue  که پارامتری اختیاری است و به عنوان مقدار در تابع callback استفاده خواهد شد.

نحوه استفاده از متد foreach‎ در جاوا اسکریپت

برای درک متد foreach‎ در جاوا اسکریپت باید در عمل آن را بررسی کنیم. همان‌طور که در بالا به آن اشاره کردیم، می‌توان از این متد برای تکرار روی عناصر آرایه‌ها و اعمال تابع callback برای هر عنصر آن آرایه استفاده کنیم. در این بخش نحوه اعلان تابع callback مناسب و نحوه استفاده از هر یک از پارامترهای آن را توضیح خواهیم داد.

در نسخه‌های قبلی جاوا اسکریپت، قبل از نسخه ES6 جاوا اسکریپت، باید یک تابع callback به‌صورت زیر اعلان می‌شد:

const ages = [20, 28, 19, 56];
const newAges = [];

ages.forEach(function (age) {
	newAges.push(age + 5);
});

console.log(newAges); 
// Output: [25, 33, 24, 61]

همچنین، این قابلیت وجود دارد که تابع callback را درجایی خارج از متد foreach‎ تعریف و با استفاده از سینتکس زیر آن را فراخوانی کرد:

const ages = [20, 28, 19, 56];
const newAges = [];

ages.forEach(increaseAgeBy5);

function increaseAgeBy5(age) {
	newAges.push(age + 5);
}

console.log(newAges); 
// Output: [25, 33, 24, 61]

هر دوی این‌ها، روش‌های بسیار خوانا و قابل‌ درکی برای استفاده از متد foreach‎ هستند. نکته قابل‌توجه اینجاست که این سینتکس حتی قابل ساده‌تر شدن هم است. از ES6 به بعد تابع callback را به‌صورت زیر فراخوانی می‌شود.

const ages = [20, 28, 19, 56];
const newAges = [];

ages.forEach((age) => {
	newAges.push(age + 5);
});

console.log(newAges); 

خروجی این قطعه کد به صورت زیر است:

(4) [25, 33, 24, 61]
0: 25
1: 33
2: 24
3: 61

دوباره این سینتکس قابل ساده‌تر شدن است و می‌توان آن را به صورت زیر هم اعمال کرد که خروجی آن با خروجی قطعه کد بالا یکسان است.

const ages = [20, 28, 19, 56];
const newAges = [];

ages.forEach((age) => newAges.push(age + 5));

console.log(newAges); 
// Output: [25, 33, 24, 61]

پارامتر اندیس یا index Parameter در foreach‎ برای چیست؟

شاخص یا اندیس پارامتری اختیاری است که می‌تواند برای ارزیابی موقعیت عنصری در آرایه اصلی استفاده شود. به عنوان مثال، می‌توانیم موقعیت و مقدار عنصر را با آن نمایش دهیم:

const languages = ['C++', 'C#', 'JS', 'Python'];

languages.forEach(function (languages, index) {
	console.log(index + ': ' + languages);
});

خروجی این قطعه کد به صورت شکل زیر است.

0: C++
1: C#
2: JS
3: Python

پارامتر آرایه یا array Parameter و نقش آن در متد foreach‎

پارامتر آرایه به خود آرایه اصلی ارجاع داده می‌شود. این هم پارامتری اختیاری برای متد foreach‎ در جاوا اسکریپت است که معمولاً به‌ندرت از آن استفاده می‌شود، زیرا از قبل به هر عنصر جداگانه دسترسی وجود دارد و می‌توان عملیات را روی آن‌ها اجرا کرد. اگر آن را به عنوان پارامتری از console.log()‎  ارسال کنیم، کل آرایه یک بار برای هر عنصر در آرایه چاپ می‌شود. مثال زیر در این رابطه آورده شده است.

const languages = ['C++', 'C#', 'JS', 'Python'];

languages.forEach(function (languages, index, array) {
	console.log(array);
});

خروجی به صورت زیر است:

(4) ["C++", "C#", "JS", "Python"]
(4) ["C++", "C#", "JS", "Python"]
(4) ["C++", "C#", "JS", "Python"]
(4) ["C++", "C#", "JS", "Python"]

معرفی فیلم های آموزش جاوا اسکریپت

فیلم های آموزش برنامه نویسی جاوا اسکریپت

جاوا اسکریپت یکی از پرکاربردترین زبان‌های برنامه نویسی است که عمده کاربرد آن در وب و ساخت اپلیکیشن موبایل به حساب می‌آید. بازار جاوا اسکریپت روزبه‌روز داغ‌تر و نیاز سازمان‌ها به متخصصان این حوزه نیز هر روز افزایش پیدا می‌کند. به‌صورت کلی می‌توان گفت که با یادگیری زبان برنامه نویسی جاوا اسکریپت شرایط ورود به بازار کار تا حدود زیادی فراهم می‌شود.

برای این هدف در پلتفرم فرادرس دوره های آموزش جامع جاوا اسکریپت زیادی قرار داده شده‌اند که به‌صورت کاملاً کاربردی به آموزش این زبان محبوب می‌پردازند. دوره‌های آموزش جاوا اسکریپت فرادرس از سطع مقدماتی تا پیشرفته در این پلتفرم موجود هستند و علاقه‌مندان به این زبان می‌توانند از این آموزش‌ها بهره ببرند. در تصویر بالا تنها تعداد کمی از دوره‌های موجود در مجموعه آموزش جاوا اسکریپت تنها به عنوان نمونه آمده‌اند.

مثال‌های رایج  از متد foreach‎ در جاوا اسکریپت

در این بخش به چند مثال جالب و قابل‌توجه از متد foreach‎ در جاوا اسکریپت می‌پردازیم. ما قرار است که اعمال حلقه روی عناصر آرایه‌ای از اشیاء و نحوه محاسبه مجموع تمام عناصر را در آرایه در قالب مثال‌هایی به صورت عملی ببینیم.

مثال هایی از متد foreach در جاوا اسکریپت

حلقه زدن در میان آرایه‌ای از اشیاء با متد foreach‎ در جاوا اسکریپت

رایج‌ترین کاربرد متد foreach‎ در جاوا اسکریپت چاپ هر عنصر یا برخی از فیلدهای آن‌ها از یک آرایه است، به مثال زیر در این رابطه توجه کنید:

const students = [
	{ firstName: 'Ali', lastName: 'Ahmadi' },
	{ firstName: 'Zahra', lastName: 'Amini' },
	{ firstName: 'Naser', lastName: 'Rasoli' },
];

students.forEach((student) => {
	console.log(`${student.firstName} ${student.lastName}`);
});
Ali Ahmadi
Zahra Amini
Naser Rasoli

چگونگی جمع عناصر آرایه یا فیلدهای آن با متد foreach در جاوا اسکریپت

در زیر مثالی از متد foreach‎ آورده شده است که آیتم‌ها را در یک آرایه اضافه کرده و مجموع را نمایش می‌دهد:

const students = [
	{ firstName: 'Ali', lastName: 'Ahmadi', tuition: 5000},
	{ firstName: 'Zahra', lastName: 'Amini', tuition: 7500 },
	{ firstName: 'Naser', lastName: 'Rasoli', tuition: 6000 },
];
sum = 0;

students.forEach((student) => {
	sum += student.tuition;
});
console.log(sum); 

خروجی به صورت زیر است:

18500

استفاده از حلقه for‌ بهتر است یا دستور foreach در جاوا اسکریپت؟

حلقه for و متد foreach‎ در جاوا اسکریپت هر دو به‌طور مشابه کار می‌کنند و در نهایت از نظر عملکرد تقریباً معادل هستند. فقط چند تفاوت بین آن‌ها وجود دارد که توجه به این تفاوت‌ها به ما کمک می‌کند تصمیم بگیریم کدام‌ یک برای قطعه کد ما بهتر است. به طور کلی می‌توان آن‌ها را در موارد زیر باهم مقایسه کرد:

  • دامنه نام متغیر
  • خوانایی کد
  • شکستن حلقه یا خروج از حلقه
  • مدیریت عناصر ازدست‌ رفته
  • «همگام‌سازی/انتظار» (async/await)

مقایسه حلقه For با foreach در جاوا اسکریپت به لحاظ دامنه نام متغیر

متد foreach‎ یک محدوده تابع دارد و همه نام متغیرها را در محدوده تابع callback خود نگه می‌دارد. اگر متغیری را خارج از متد foreach‎ تعریف کنیم و از آن در حلقه استفاده کنیم، تضاد به وجود می‌آید و از callback استفاده می‌شود. برای مثال، فرض کنید یک «ثابت» (Const) به نام student ایجاد کردیم و نام Reza را به محدوده آن اختصاص می‌دهیم.

اگر روی دانش‌آموزانی که هرکدام به عنوان student نشان داده می‌شوند، پیمایش انجام شود، تضاد نام متغیرها را خواهیم داشت. مثال زیر همچین چیزی را نشان میدهد.

const student = 'Reza';
const students = ['Ali', 'Zahra', 'Naser', 'Amin'];

students.forEach((student) => {
	console.log(student); 
console.log(student);

خروجی به صورت زیر است:

Expected ";" but found "student"
به صورت کلی استفاده چند بار از یک نام متغیر کار خوبی نیست و فقط کد را پیچیده خواهد کرد.
مطلب پیشنهادی:
حلقه for در جاوا اسکریپت — از صفر تا صد + مثال و کد
در این مطلب، با حلقه for در جاوا اسکریپت آشنا می‌شویم و با مثال‌های مختلف، کاربرد حلقه for را یاد می‌گیریم.

مدیریت عناصر از دست‌ رفته با حقله for و متد foreach‎ در جاوا اسکریپت

حلقه for و متد foreach‎ در جاوا اسکریپت عناصر گم شده یا مقادیر از دست رفته را به‌طور متفاوتی مدیریت می‌کنند. فرض کنید یک آرایه داریم که برخی از عناصر در آن وجود ندارد:

const students = ['Ali', , 'Zahra', 'Naser', , 'Amin'];

با نگاهی به آرایه بالا، متوجه خواهیم شد که برخی از عناصر گم شده‌اند. ابتدا، بهتر است روی آرایه دانشجویی با حلقه for پیمایش انجام شود تا مشخص شود مقادیر از دست رفته در حلقه for چگونه مدیریت می‌شود:

const students = ['Ali', , 'Zahra', 'Naser', , 'Amin'];
const studentsList = [];

for (let i = 0; i < students.length; i++) {
	studentsList.push(students[i]);
}
console.log(studentsList); 

خروجی به صورت زیر است:

(6) ["Ali", undefined, "Zahra", "Naser",...]
0: "Ali"
1: undefined
2: "Zahra"
3: "Naser"
4: undefined
5: "Amin"
در قطعه کد بالا، متوجه خواهیم شد که مقداری نامشخص در اولین و چهارمین اندیس دریافت شده است. حلقه for عناصر از دست‌ رفته را به عنوان مقادیر «تعریف نشده» (Undefined) در نظر می‌گیرد. حال، نحوه برخورد متد foreach‎ را در جاوا اسکریپت با مقادیر گم شده در آرایه students بیندازیم:
const students = ['Ali', , 'Zahra', 'Naser', , 'Amin'];
const studentsList = [];

students.forEach(function (student) {
	studentsList.push(student);
});

console.log(studentsList); 

خروجی به صورت زیر است:

(4) ["Ali", "Zahra", "Naser", "Amin"]
0: "Ali"
1: "Zahra"
2: "Naser"
3: "Amin"
foreach در جاوا اسکریپت از شکاف مقادیر ازدست‌رفته می‌گذرد و کار را ادامه می‌دهد.

مقایسه حلقه For با foreach در جاوا اسکریپت به لحاظ خوانایی کد

این کاملاً به ما بستگی دارد که تصمیم بگیریم کدام روش حلقه زدن را انتخاب کنیم. متد foreach‎ مطمئناً سینتکس مختصرتری دارد، بنابراین اگر خوانایی کد در فهرست اولویت‌های ما باشد، متد foreach‎ در جاوا اسکریپت نسبت به حلقه for برای ما باید ارجحیت داشته باشد.

در این بخش، نمونه کدهایی را خواهیم آورد تا با استفاده از آنها تصمیم بگیریم که خواندن و درک کدام روش برای حلقه کردن آرایه‌ها آسان‌تر است. فرض کنید مجموعه‌ای از دانش‌آموزان داریم. هر دانش‌آموز دارای نام و مجموعه‌ای از دوره‌هایی است که در آن شرکت می‌کند:

const students = [
	{ name: 'ALI', courses: ['C++', 'C#', 'JS'] },
	{ name: 'Zahra', courses: ['C#', 'Python', 'R'] },
];

ما می‌توانیم با استفاده از دو حلقه for در جاوا اسکریپت این کار را انجام دهیم. اولین حلقه روی همه دانش‌آموزان تکرار می‌شود و نام دانش‌آموز را ثبت می‌کند. حلقه دوم در تمام دوره‌هایی که دانش‌آموز فعلی شرکت می‌کند تکرار می‌شود و آن‌ها را یکی‌یکی ثبت می‌کند:

for (let i = 0; i < students.length; i++) {
	let student = students[i];
	console.log(student);

	for (let k = 0; k < student.courses.length; k++) {
		let subject = student.courses[k];
		console.log(subject);
	}
}

خروجی به صورت زیر است:

(2) {name: "ALI", courses: Array(3)}
C++
C#
JS
(2) {name: "Zahra", courses: Array(3)}
C#
Python
R
حلقه for از ما می‌خواهد با استفاده از متغیرهای موقت i و k به آرایه دسترسی داشته باشیم. این کد ممکن است نامرتب به نظر برسد و می‌تواند سردرگمی زیادی را به همراه داشته باشد.
students.forEach((student) => {
	console.log(student);
	student.courses.forEach((subject) => {
		console.log(subject);
	});
});

حلقه foreach‎ در جاوا اسکریپت به ما کمک می‌کند تا از شر متغیرهای «شمارنده موقت» (Temporary counter) خلاص شویم و خواندن و درک کدها را بسیار آسان‌تر می‌کند. این روش از یک تابع callback استفاده می‌کند و آن را برای هر عنصر در آرایه اعمال می‌کند، به این معنی که برای دریافت هر عنصر نیازی به استفاده از علامت کروشه نداریم. خروجی همانند خروجی حلقه for خواهد بود.

مقایسه حلقه For و foreach در جاوا اسکریپت در خصوص خروج از حلقه

تاکنون، فقط در مورد مزیت‌های foreach‎ در جاوا اسکریپت در مقابل حلقه‌های for بحث شد؛ اما یکی از مزیت‌های مشخص حلقه for توانایی آن برای خروج زودهنگام از یک حلقه در صورت لزوم است.

به عنوان ‌مثال، فرض کنیم می‌خواهیم فقط یک دانش‌آموز به نام Amin را از آرایه دانشجویان برگردانیم. ما باید روی هر دانش‌آموز در آرایه تکرار انجام دهیم، بررسی کنیم که آیا نام آن Amin است یا خیر و اگر دانش‌آموز پیدا شد، از حلقه خارج شویم.

ممکن است فکر کنید که می‌توانیم از هر دو حلقه for و foreach‎ برای تکرار روی آرایه دانشجویی استفاده کنیم؛ اما درواقع، اگر سعی کنیم از break در داخل حلقه foreach‎ استفاده کنیم، یک «خطای سینتکس» (SyntaxError) ایجاد می‌کند. بنابراین، اگر نیاز داریم که از حلقه خارج شویم، احتمالاً باید از حلقه for استفاده کنیم:

const students = ['Ali', 'Zahra', 'Naser', 'Aida', 'Amin'];

for (let i = 0; i < students.length; i++) {
	if (students[i].name === 'Amin') {
		console.log(`>> ${students[i].name} is the most brilliant lady in the class`);
		break;
	}
    console.log(`> Name of the current student is ${students[i]}`);
}

خروجی به صورت زیر است:

> Name of the current student is Ali
> Name of the current student is Zahra
> Name of the current student is Naser
> Name of the current student is Aida
> Name of the current student is Amin

همگام‌سازی و انتظار با حلقه For و foreach در جاوا اسکریپت

حلقه foreach‎ در جاوا اسکریپت با توابع async سازگار نیست. حتی اگر یک تابع async را در داخل بلوک foreach‎ اعلام کنیم، آن‌طور که انتظار می‌رود رفتار نخواهد کرد.

همگام‌سازی و انتظار با متد forEach

هیچ راهی برای انجام عمل async/wait با حلقه foreach‎ وجود ندارد؛ بنابراین، اگر بخواهیم در کد از این ویژگی‌های استفاده کنیم، به‌جای آن از حلقه for استفاده می‌کنیم.

مطلب پیشنهادی:
معرفی جاوا اسکریپت ناهمگام — به زبان ساده
در این مقاله به اختصار به بررسی مشکلات مرتبط با جاوا اسکریپت ناهمگام می‌پردازیم. همچنین برخی از تکنیک‌های مختلف برنامه‌نویسی ناهمگام را بررسی می‌کنیم.

استفاده از forEach با دیگر ساختارهای داده در جاوا اسکریپت

در درجه اول، متد forEach برای پیمایش آرایه‌ استفاده می‌شود. از طرف دیگر، می‌توان از آن برای پیمایش سایر ساختارهای داده مانند: مجموعه‌ها و نقشه‌ها استفاده کرد. در این بخش، چند مثال ساده بررسی خواهد شد که نشان می‌دهد، چگونه از حلقه forEach در جاوا اسکریپت می‌توان با سایر عناصر داده استفاده کرد.

پیمایش مجموعه داده با متد forEach

می‌توان با استفاده از متد forEach روی یک «مجموعه داده» (Set) پیمایش انجام داد. مثال زیر بیانگر این موضوع است:

const nums = new Set([11, 25, 35, 47, 25, 47]);

nums.forEach(myFunction);

function myFunction(num) {
	console.log(num);
}

خروجی به شکل زیر است:

11
25
35
47

پیمایش نقشه با متد forEach در جاوا اسکریپت

می‌توان عمل پیمایش یا همان حلقه زدن را روی ساختار داده «نقشه» (map) مطابق مثال زیر انجام داد. نقشه مجموعه‌ای از عناصر است که در آن هر عنصر به‌عنوان جفت کلید - مقدار ذخیره می‌شود. شی‌ء نقشه می‌تواند هم اشیا و هم مقادیر اولیه را به‌عنوان کلید یا مقدار نگه دارد. وقتی روی شی‌ء نقشه تکرار یا پیمایش انجام شود، جفت کلید - مقدار به همان ترتیبی که درج‌شده است، برمی‌گرداند.

// Declaring map
const map = new Map();

// Inserting key/value pairs
map.set('greeting', 'Hello');
map.set('firstName', 'John');
map.set('lastName', 'Doe');

// Loop through with forEach
map.forEach((value, key) => {
	console.log(`${key} - ${value}`);
});

خروجی به صورت زیر است:

greeting - Hello
firstName - John
lastName - John

سخن پایانی

در این راهنما، نگاهی به نحوه عملکرد حلقه foreach‎ درجاوا اسکریپت داشتیم و مشخص شد که چگونه می‌توان از آن برای حلقه زدن و پیمایش در عناصر آرایه‌ها استفاده کرد. همچنین در مورد آرگومان‌های همراه آن، مانند index ، currentElement  و array  بحث شد.

در نهایت، چندین مثال را بررسی و تفاوت بین حلقه foreach‎ و حلقه for را پوشش داده شد. امید است که این آموزش مورد توجه واقع‌ شود. منتظر انتقادات و پیشنهاد‌های شما در بخش نظرات هستیم.

اگر این مطلب برای شما مفید بوده است، آموزش‌ها و مطالب زیر نیز به شما پیشنهاد می‌شوند:

بر اساس رای ۰ نفر
آیا این مطلب برای شما مفید بود؟
شما قبلا رای داده‌اید!
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.

کامل بهرامی دانش‌آموخته کارشناسی ارشد رشته مهندسی کامپیوتر گرایش نرم‌افزار از دانشگاه ارومیه است. به حوزه کامپیوتر، برنامه‌نویسی و فناوری اطلاعات علاقه‌مند‌ است و در حوزه‌های مذکور در مجله فرادرس محتوا تولید می‌کند.