تعریف توابع در زبان جاوا اسکریپت

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


توابع

توابع و یا Function  ها بلوک های سازنده یک برنامه هستند. آنها این امکان را به ما می‌دهند که کدهای تکراری برنامه را بدون تکرار دوباره آنها ، در قسمتهای مختلف برنامه فراخوانی کنیم. در فصول قبل با بعضی از توابع درونی جاوا اسکریپت  همانند(alert(message) ، prompt(message, default و (confirm(question آشنا شدیم. اما اکنون می‌خواهیم توابعی  که به آنها نیاز داریم را خودمان طراحی کنیم.


تعریف تابع

برای ایجاد یک تابع می توانیم از تعریف یک تابع استفاده کنیم. برای مثال :

function showMessage() {
  alert( 'Hello everyone!' );
}

در ابتدا کلمه function آورده میشود و سپس نامی دلخواه را برای تابع خود مشخص میکنیم و بعد از آن لیستی از پارامترهایی که می توانند داخل پرانتز های تابع قرار بگیرند را تعیین میکنیم (در مورد مساله بالا پارامتری مشخص نشده است). در نهایت بدنه تابع رابین کروشه ها قرار می دهیم :


function_basics
تابع ذکر شده در بالا را به این صورت می‌توان فراخوانی کرد : ()showMessage. برای مثال :

function showMessage() {
  alert( 'Hello everyone!' );
}

showMessage();
showMessage();

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


متغیرهای محلی

متغیری که در داخل یک function تعریف می‌شود، تنها داخل همان تابع قابل استفاده است. برای مثال :

function showMessage() {
  let message = "Hello, I'm JavaScript!"; // local variable

  alert( message );
}

showMessage(); // Hello, I'm JavaScript!

alert( message ); // <-- Error! The variable is local to the function

متغیرهای بیرونی

یک تابع می‌تواند به متغیرهای بیرونی هم دسترسی داشته باشد. برای مثال :

let userName = 'John';

function showMessage() {
  let message = 'Hello, ' + userName;
  alert(message);
}

showMessage(); // Hello, John

توابع دسترسی کامل به متغیرهای بیرونی دارند و می‌توانند آنها را تغییر دهند :

let userName = 'John';

function showMessage() {
  userName = "Bob"; // (1) changed the outer variable

  let message = 'Hello, ' + userName;
  alert(message);
}

alert( userName ); // John before the function call

showMessage();

alert( userName ); // Bob, the value was modified by the function

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

let userName = 'John';

function showMessage() {
  let userName = "Bob"; // declare a local variable

  let message = 'Hello, ' + userName; // Bob
  alert(message);
}

// the function will create and use its own userName
showMessage();

alert( userName ); // John, unchanged, the function did not access the outer variable

متغیرهایی که در خارج از توابع اعلام می‌شوند مانند متغیر بیرونی userName در مثال فوق ، متغیر های سراسری نامیده می شوند. متغیر های سراسری در هر تابعی قابل استفاده هستند (مگر در موردی که به وسیله متغیرهای محلی همنام نادیده گرفته شوند)

معمولاً یک تابع تمام متغیرهایی که به آن نیاز دارد را در داخل خود تعریف میکند. متغیر های سراسری تنها داده هایی در سطح کل پروژه را در خود ذخیره میکنند. کد های مدرن خیلی کم از متغیرهای سراسری استفاده می کنند.


پارامترها

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

در نمونه مثال زیر تابع مورد نظر دارای دو پارامتر است : from و text

function showMessage(from, text) { // arguments: from, text
  alert(from + ': ' + text);
}

showMessage('Ann', 'Hello!'); // Ann: Hello! (*)
showMessage('Ann', "What's up?"); // Ann: What's up? (**)

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

function showMessage(from, text) {

  from = '*' + from + '*'; // make "from" look nicer

  alert( from + ': ' + text );
}

let from = "Ann";

showMessage(from, "Hello"); // *Ann*: Hello

// the value of "from" is the same, the function modified a local copy
alert( from ); // Ann

مقادیر پیش فرض

اگر پارامتری در فراخوانی تابع  نادیده گرفته شود مقدار آن undefined می‌شود. برای نمونه تابع ذکر شده در فوق(showMessage(from, text را می‌توان با یک پارامتر فراخوانی کرد :

showMessage("Ann");

در این حالت خطایی وجود ندارد خروجی چنین فراخوانی عبارت است از "Ann: undefined" . در اینجا پارامتر دومی وجود ندارد بنابراین فرض می شود که text === undefined .

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

function showMessage(from, text = "no text given") {
  alert( from + ": " + text );
}

showMessage("Ann"); // Ann: no text given

اکنون اگر پارامتر دوم در فراخوانی نادیده گرفته شود، مقدار "no text given" به جای آن در نظر گرفته می شود. در اینجا "no text given" یک رشته است اما می توان عبارتی پیچیده تر را در اینجا در نظر گرفت. برای مثال فراخوانی تابع ای دیگر :

function showMessage(from, text = anotherFunction()) {
  // anotherFunction() only executed if no text given
  // its result becomes the value of text
}


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

function showMessage(from, text) {
  if (text === undefined) {
    text = 'no text given';
  }

  alert( from + ": " + text );
}

 


بازگشت یک مقدار

یک تابع می‌تواند مقداری را در هنگام فراخوانی تابع به عنوان نتیجه بازگرداند. نمونه مثال ساده زیر جمع دو عدد را به عنوان نتیجه بازمی‌گرداند :

function sum(a, b) {
  return a + b;
}

let result = sum(1, 2);
alert( result ); // 3

کلمه رزرو شده return را می توان در هر قسمتی از تابع قرار داد.  وقتی نوبت به اجرای این کلمه می رسد تابع متوقف شده و مقدار آن برگشت داده میشود.

می توان از چندین کلمه return در یک تابع استفاده کرد. برای مثال :

function checkAge(age) {
  if (age > 18) {
    return true;
  } else {
    return confirm('Got a permission from the parents?');
  }
}

let age = prompt('How old are you?', 18);

if ( checkAge(age) ) {
  alert( 'Access granted' );
} else {
  alert( 'Access denied' );
}

میتوان از کلمه return بدون هیچ مقداری استفاده کرد. این باعث خروج فوری از تابع میشود. برای مثال :

function showMovie(age) {
  if ( !checkAge(age) ) {
    return;
  }

  alert( "Showing you the movie" ); // (*)
  // ...
}

در نمونه مثال فوق اگر (checkAge(age مقدار false ارزیابی شود پیغام alert اجرا نخواهد شد.

اگر یک تابع مقداری را برنگرداند همانند این است که آن تابع مقدار undefined را باز می گرداند.

function doNothing() { /* empty */ }

alert( doNothing() === undefined ); // true

وقتی از return بدون مقداری استفاده می‌کنیم نیز همانند این است که از return undefined استفاده کردیم :

function doNothing() {
  return;
}

alert( doNothing() === undefined ); // true

نامگذاری توابع

یک تابع عملی است که می‌خواهیم انجام دهیم. بنابراین نام تابع باید یک فعل باشد. نام باید مختصر و بیانگر عمل مورد نظر باشد. برای مثال نام توابعی که با کلمه "show" آغاز می شوند معمولا برای نمایش چیزی استفاده میشوند توابعی که با کلمات زیر آغاز می شوند :
 

  • "get…" - یک مقدار را برمیگردانند
  • "calc…" -  چیزی را محاسبه میکنند
  • "create…" - چیزی را ایجاد می کنند
  • "check…" - چیزی را بررسی کرده و یک مقدار بولین برمیگردانند

 برای مثال :

showMessage(..)     // shows a message
getAge(..)          // returns the age (gets it somehow)
calcSum(..)         // calculates a sum and returns the result
createForm(..)      // creates a form (and usually returns it)
checkPermission(..) // checks a permission, returns true/false

یک تابع یک عمل

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

  • getAge -  اگر چنین تابعی مقدار سن را در یک alert نمایش دهد، این بد است. این تابع فقط باید مقدار سن را برگرداند نه آنکه آن را نمایش دهد.
  • createForm - اگر چنین تابعی یک سند را ویرایش کند و یا چیزی به آن بیافزاید، این بد است. این تابع تنها باید چیزی را بسازد و آن را برگشت دهد.
     
منتشر شده در ۲۵ خرداد ۱۳۹۷ حمید رضا ملکی ۲۳۹۱ بازدید
دیدگاه ها

هنوز دیدگاهی ثبت نشده

برای ارسال دیدگاه لازم است ابتدا وارد سایت شوید