You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
16 KiB
210 lines
16 KiB
<!--
|
|
CO_OP_TRANSLATOR_METADATA:
|
|
{
|
|
"original_hash": "92e136090efc4341b1d51c37924c1802",
|
|
"translation_date": "2025-08-29T14:31:47+00:00",
|
|
"source_file": "2-js-basics/2-functions-methods/README.md",
|
|
"language_code": "fa"
|
|
}
|
|
-->
|
|
# اصول اولیه جاوااسکریپت: متدها و توابع
|
|
|
|

|
|
> طراحی توسط [Tomomi Imura](https://twitter.com/girlie_mac)
|
|
|
|
## آزمون پیش از درس
|
|
[آزمون پیش از درس](https://ff-quizzes.netlify.app)
|
|
|
|
وقتی به نوشتن کد فکر میکنیم، همیشه باید مطمئن شویم که کد ما خوانا است. شاید این موضوع کمی غیرمنطقی به نظر برسد، اما کد بسیار بیشتر از آنکه نوشته شود، خوانده میشود. یکی از ابزارهای اصلی در جعبهابزار یک توسعهدهنده برای اطمینان از نگهداری آسان کد، **تابع** است.
|
|
|
|
[](https://youtube.com/watch?v=XgKsD6Zwvlc "متدها و توابع")
|
|
|
|
> 🎥 برای مشاهده ویدئویی درباره متدها و توابع، روی تصویر بالا کلیک کنید.
|
|
|
|
> میتوانید این درس را در [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-functions/?WT.mc_id=academic-77807-sagibbon) مطالعه کنید!
|
|
|
|
## توابع
|
|
|
|
در اصل، یک تابع بلوکی از کد است که میتوانیم آن را به صورت دلخواه اجرا کنیم. این ویژگی برای سناریوهایی که نیاز داریم یک کار را چندین بار انجام دهیم بسیار مناسب است؛ به جای اینکه منطق را در چندین مکان تکرار کنیم (که بهروزرسانی آن را دشوار میکند)، میتوانیم آن را در یک مکان متمرکز کنیم و هر زمان که نیاز به انجام عملیات داشتیم، آن را فراخوانی کنیم - حتی میتوانید توابع را از داخل توابع دیگر فراخوانی کنید!
|
|
|
|
یکی دیگر از ویژگیهای مهم توابع، امکان نامگذاری آنها است. شاید این موضوع پیشپاافتاده به نظر برسد، اما نام تابع راهی سریع برای مستندسازی بخشی از کد فراهم میکند. میتوانید این را مانند برچسبی روی یک دکمه تصور کنید. اگر روی دکمهای که نوشته "لغو تایمر" کلیک کنم، میدانم که قرار است ساعت را متوقف کند.
|
|
|
|
## ایجاد و فراخوانی یک تابع
|
|
|
|
سینتکس یک تابع به شکل زیر است:
|
|
|
|
```javascript
|
|
function nameOfFunction() { // function definition
|
|
// function definition/body
|
|
}
|
|
```
|
|
|
|
اگر بخواهم یک تابع برای نمایش یک پیام خوشآمدگویی ایجاد کنم، ممکن است به این شکل باشد:
|
|
|
|
```javascript
|
|
function displayGreeting() {
|
|
console.log('Hello, world!');
|
|
}
|
|
```
|
|
|
|
هر زمان که بخواهیم تابع خود را فراخوانی (یا اجرا) کنیم، از نام تابع به همراه `()` استفاده میکنیم. لازم به ذکر است که تابع ما میتواند قبل یا بعد از تصمیم به فراخوانی آن تعریف شود؛ کامپایلر جاوااسکریپت آن را برای شما پیدا خواهد کرد.
|
|
|
|
```javascript
|
|
// calling our function
|
|
displayGreeting();
|
|
```
|
|
|
|
> **NOTE:** نوع خاصی از تابع وجود دارد که به آن **متد** گفته میشود و شما قبلاً از آن استفاده کردهاید! در واقع، این را در دمو بالا دیدیم وقتی از `console.log` استفاده کردیم. تفاوت متد با تابع این است که متد به یک شیء متصل است (در مثال ما `console`)، در حالی که تابع آزاد است. بسیاری از توسعهدهندگان این اصطلاحات را بهطور متناوب استفاده میکنند.
|
|
|
|
### بهترین روشها برای توابع
|
|
|
|
هنگام ایجاد توابع، چند نکته مهم وجود دارد که باید در نظر داشته باشید:
|
|
|
|
- همانطور که همیشه، از نامهای توصیفی استفاده کنید تا بدانید تابع چه کاری انجام میدهد
|
|
- از **camelCasing** برای ترکیب کلمات استفاده کنید
|
|
- توابع خود را بر روی یک وظیفه خاص متمرکز کنید
|
|
|
|
## ارسال اطلاعات به یک تابع
|
|
|
|
برای اینکه یک تابع قابل استفادهتر باشد، اغلب میخواهید اطلاعاتی را به آن ارسال کنید. اگر مثال `displayGreeting` بالا را در نظر بگیریم، فقط **سلام، دنیا!** را نمایش میدهد. این خیلی کاربردی نیست. اگر بخواهیم آن را کمی انعطافپذیرتر کنیم، مانند اجازه دادن به کسی برای مشخص کردن نام فردی که باید خوشآمد گفته شود، میتوانیم یک **پارامتر** اضافه کنیم. پارامتر (که گاهی اوقات **آرگومان** نیز نامیده میشود)، اطلاعات اضافی است که به یک تابع ارسال میشود.
|
|
|
|
پارامترها در بخش تعریف داخل پرانتز فهرست میشوند و با کاما جدا میشوند، مانند زیر:
|
|
|
|
```javascript
|
|
function name(param, param2, param3) {
|
|
|
|
}
|
|
```
|
|
|
|
میتوانیم `displayGreeting` خود را بهروزرسانی کنیم تا یک نام را بپذیرد و آن را نمایش دهد.
|
|
|
|
```javascript
|
|
function displayGreeting(name) {
|
|
const message = `Hello, ${name}!`;
|
|
console.log(message);
|
|
}
|
|
```
|
|
|
|
وقتی میخواهیم تابع خود را فراخوانی کنیم و پارامتر را ارسال کنیم، آن را در داخل پرانتز مشخص میکنیم.
|
|
|
|
```javascript
|
|
displayGreeting('Christopher');
|
|
// displays "Hello, Christopher!" when run
|
|
```
|
|
|
|
## مقادیر پیشفرض
|
|
|
|
میتوانیم تابع خود را حتی انعطافپذیرتر کنیم با اضافه کردن پارامترهای بیشتر. اما اگر نخواهیم هر مقدار مشخص شود چه؟ با مثال خوشآمدگویی، میتوانیم نام را بهعنوان ضروری باقی بگذاریم (ما باید بدانیم به چه کسی خوشآمد میگوییم)، اما میخواهیم اجازه دهیم خود پیام خوشآمدگویی به دلخواه سفارشی شود. اگر کسی نخواهد آن را سفارشی کند، یک مقدار پیشفرض ارائه میدهیم. برای ارائه مقدار پیشفرض به یک پارامتر، آن را به همان روشی که برای یک متغیر مقدار تعیین میکنیم تنظیم میکنیم - `parameterName = 'defaultValue'`. برای مشاهده یک مثال کامل:
|
|
|
|
```javascript
|
|
function displayGreeting(name, salutation='Hello') {
|
|
console.log(`${salutation}, ${name}`);
|
|
}
|
|
```
|
|
|
|
وقتی تابع را فراخوانی میکنیم، میتوانیم تصمیم بگیریم که آیا میخواهیم برای `salutation` مقداری تنظیم کنیم یا نه.
|
|
|
|
```javascript
|
|
displayGreeting('Christopher');
|
|
// displays "Hello, Christopher"
|
|
|
|
displayGreeting('Christopher', 'Hi');
|
|
// displays "Hi, Christopher"
|
|
```
|
|
|
|
## مقادیر بازگشتی
|
|
|
|
تا اینجا، تابعی که ساختیم همیشه خروجی را به [کنسول](https://developer.mozilla.org/docs/Web/API/console) ارسال میکند. گاهی اوقات این دقیقاً همان چیزی است که به دنبال آن هستیم، بهویژه زمانی که توابعی ایجاد میکنیم که خدمات دیگری را فراخوانی میکنند. اما اگر بخواهم یک تابع کمکی برای انجام یک محاسبه ایجاد کنم و مقدار را بازگردانم تا بتوانم آن را در جای دیگری استفاده کنم چه؟
|
|
|
|
میتوانیم این کار را با استفاده از یک **مقدار بازگشتی** انجام دهیم. مقدار بازگشتی توسط تابع بازگردانده میشود و میتوان آن را در یک متغیر ذخیره کرد، درست همانطور که میتوانیم یک مقدار ثابت مانند یک رشته یا عدد را ذخیره کنیم.
|
|
|
|
اگر یک تابع چیزی را بازگرداند، از کلمه کلیدی `return` استفاده میشود. کلمه کلیدی `return` انتظار دارد یک مقدار یا مرجع از چیزی که بازگردانده میشود، مانند زیر:
|
|
|
|
```javascript
|
|
return myVariable;
|
|
```
|
|
|
|
میتوانیم یک تابع برای ایجاد یک پیام خوشآمدگویی ایجاد کنیم و مقدار را به فراخواننده بازگردانیم.
|
|
|
|
```javascript
|
|
function createGreetingMessage(name) {
|
|
const message = `Hello, ${name}`;
|
|
return message;
|
|
}
|
|
```
|
|
|
|
وقتی این تابع را فراخوانی میکنیم، مقدار را در یک متغیر ذخیره میکنیم. این دقیقاً همان روشی است که یک متغیر را به یک مقدار ثابت تنظیم میکنیم (مانند `const name = 'Christopher'`).
|
|
|
|
```javascript
|
|
const greetingMessage = createGreetingMessage('Christopher');
|
|
```
|
|
|
|
## توابع بهعنوان پارامتر برای توابع
|
|
|
|
همانطور که در مسیر برنامهنویسی خود پیشرفت میکنید، با توابعی مواجه خواهید شد که توابع را بهعنوان پارامتر میپذیرند. این ترفند جالب معمولاً زمانی استفاده میشود که نمیدانیم چه زمانی چیزی اتفاق میافتد یا کامل میشود، اما میدانیم که باید در پاسخ به آن عملی انجام دهیم.
|
|
|
|
بهعنوان مثال، [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) را در نظر بگیرید، که یک تایمر را شروع میکند و کدی را اجرا میکند وقتی که کامل شد. باید به آن بگوییم که چه کدی را میخواهیم اجرا کنیم. به نظر میرسد که این کار مناسب یک تابع است!
|
|
|
|
اگر کد زیر را اجرا کنید، پس از ۳ ثانیه پیام **۳ ثانیه گذشته است** را مشاهده خواهید کرد.
|
|
|
|
```javascript
|
|
function displayDone() {
|
|
console.log('3 seconds has elapsed');
|
|
}
|
|
// timer value is in milliseconds
|
|
setTimeout(displayDone, 3000);
|
|
```
|
|
|
|
### توابع ناشناس
|
|
|
|
بیایید دوباره به چیزی که ساختیم نگاه کنیم. ما یک تابع با نام ایجاد میکنیم که فقط یک بار استفاده خواهد شد. همانطور که برنامه ما پیچیدهتر میشود، میتوانیم خودمان را در حال ایجاد تعداد زیادی تابع ببینیم که فقط یک بار فراخوانی میشوند. این ایدهآل نیست. همانطور که مشخص است، همیشه نیازی به ارائه نام نداریم!
|
|
|
|
وقتی یک تابع را بهعنوان پارامتر ارسال میکنیم، میتوانیم از ایجاد آن در پیش صرفنظر کنیم و بهجای آن آن را بهعنوان بخشی از پارامتر بسازیم. از همان کلمه کلیدی `function` استفاده میکنیم، اما بهجای آن آن را بهعنوان پارامتر میسازیم.
|
|
|
|
بیایید کد بالا را بازنویسی کنیم تا از یک تابع ناشناس استفاده کنیم:
|
|
|
|
```javascript
|
|
setTimeout(function() {
|
|
console.log('3 seconds has elapsed');
|
|
}, 3000);
|
|
```
|
|
|
|
اگر کد جدید ما را اجرا کنید، متوجه خواهید شد که همان نتایج را دریافت میکنیم. ما یک تابع ایجاد کردیم، اما نیازی به دادن نام به آن نداشتیم!
|
|
|
|
### توابع فلش (Fat Arrow)
|
|
|
|
یکی از میانبرهای رایج در بسیاری از زبانهای برنامهنویسی (از جمله جاوااسکریپت) توانایی استفاده از چیزی است که به آن **تابع فلش** یا **تابع پیکان چاق** گفته میشود. این تابع از یک نشانگر خاص `=>` استفاده میکند که شبیه یک پیکان است - به همین دلیل نامگذاری شده است! با استفاده از `=>`، میتوانیم از کلمه کلیدی `function` صرفنظر کنیم.
|
|
|
|
بیایید کد خود را یک بار دیگر بازنویسی کنیم تا از یک تابع فلش استفاده کنیم:
|
|
|
|
```javascript
|
|
setTimeout(() => {
|
|
console.log('3 seconds has elapsed');
|
|
}, 3000);
|
|
```
|
|
|
|
### زمان استفاده از هر استراتژی
|
|
|
|
اکنون دیدهاید که سه روش برای ارسال یک تابع بهعنوان پارامتر داریم و ممکن است بپرسید که چه زمانی از هرکدام استفاده کنیم. اگر میدانید که تابع را بیش از یک بار استفاده خواهید کرد، آن را بهصورت معمولی ایجاد کنید. اگر فقط برای یک مکان استفاده خواهد شد، معمولاً بهتر است از یک تابع ناشناس استفاده کنید. اینکه آیا از تابع فلش استفاده کنید یا سینتکس سنتی `function`، به شما بستگی دارد، اما خواهید دید که اکثر توسعهدهندگان مدرن `=>` را ترجیح میدهند.
|
|
|
|
---
|
|
|
|
## 🚀 چالش
|
|
|
|
آیا میتوانید تفاوت بین توابع و متدها را در یک جمله توضیح دهید؟ امتحان کنید!
|
|
|
|
## آزمون پس از درس
|
|
[آزمون پس از درس](https://ff-quizzes.netlify.app)
|
|
|
|
## مرور و مطالعه شخصی
|
|
|
|
ارزش دارد که [کمی بیشتر درباره توابع فلش مطالعه کنید](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions)، زیرا آنها بهطور فزایندهای در کدها استفاده میشوند. تمرین کنید که یک تابع بنویسید و سپس آن را با این سینتکس بازنویسی کنید.
|
|
|
|
## تکلیف
|
|
|
|
[سرگرمی با توابع](assignment.md)
|
|
|
|
---
|
|
|
|
**سلب مسئولیت**:
|
|
این سند با استفاده از سرویس ترجمه هوش مصنوعی [Co-op Translator](https://github.com/Azure/co-op-translator) ترجمه شده است. در حالی که ما برای دقت تلاش میکنیم، لطفاً توجه داشته باشید که ترجمههای خودکار ممکن است شامل خطاها یا نادرستیهایی باشند. سند اصلی به زبان اصلی آن باید به عنوان منبع معتبر در نظر گرفته شود. برای اطلاعات حساس، ترجمه حرفهای انسانی توصیه میشود. ما هیچ مسئولیتی در قبال سوءتفاهمها یا تفسیرهای نادرست ناشی از استفاده از این ترجمه نداریم. |