پارامترها در توابع جاوا اسکریپتی

02 فروردین 1398
Advanced-Javascript-function-parameters

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

پارامترها در توابع

اگر از دوره ی قبل به یاد داشته باشید، توابع جاوا اسکریپتی می توانستند مقادیری به نام پارامتر یا آرگومان بگیرند:

function functionName(parameter1, parameter2, parameter3) {
  // کد های مورد نظر ما برای اجرا شدن
}

و در مورد تفاوت کلمات «پارامتر» و «آرگومان» توضیح دادیم که:

  • پارامترها نام هایی هستند که در هنگام تعریف تابع به آن داده می شوند (مانند مثال بالا).
  • آرگومان ها مقادیر واقعی هستند که هنگام اجرای تابع به آن داده می شوند.

توابع جاوا اسکریپت هیچ تست و آزمایشی روی پارامترهای خود انجام نمی دهند بنابراین هیچ نوع داده ی مشخص شده ای وجود ندارد و شما می توانید هر مقداری را به توابع پاس دهید. با توجه به این مسئله اگر به توابع تعداد آرگومان هایی کافی داده نشود (به طور مثال یکی از آرگومان ها را به تابع ندهیم)، تابع به صورت خودکار به جای آن آرگومان ها مقدار undefined قرار می دهد.

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

<!DOCTYPE html>
<html>
<body>

<p>Setting a default value to a function parameter.</p>
<p id="demo"></p>

<script>
function myFunction(x, y) {
  if (y === undefined) {
    y = 0;
  }  
  return x * y;
}
document.getElementById("demo").innerHTML = myFunction(4);
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

به همین شکل و با استفاده از یک شرط اضافی می توانیم از ایجاد مقادیر undefined جلوگیری کنیم. البته نکته ی جالب اینجاست که در ECMAScript 2015 می توان این کار را به شکل بسیار راحت تری انجام داد:

function (a=1, b=1) { // function code }

سوال: ECMAScript 2015 در چه مرورگرهایی پشتیبانی می شود؟

پاسخ: از نامش مشخص است! تمام مرورگر های امروزی از آن پشتیبانی می کنند و مشکلی در اجرای کدهایتان نخواهید داشت. Internet Explorer 9, Firefox 4 Chrome 5, Safari 5 و نسخه های بعدی شان تماما از آن پشتیبانی می کنند. می توانید به صفحه ی kangax.github.io مراجعه و به صورت مفصل و لیست شده انواع پشتیبانی های مرورگر های مختلف را مشاهده کنید. در یک کلام، با خیال راحت از آن استفاده کنید.

Arguments Object (شیء آرگومان)

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

<!DOCTYPE html>
<html>
<body>

<p>Finding the largest number.</p>
<p id="demo"></p>

<script>
function findMax() {
  var i;
  var max = -Infinity;
  for(i = 0; i < arguments.length; i++) {
    if (arguments[i] > max) {
      max = arguments[i];
    }
  }
  return max;
} 
document.getElementById("demo").innerHTML = findMax(4, 5, 6);
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

در این تابع به کلمات arguments و max توجه داشته باشید، اینها از شیء آرگومان می آیند.

همچنین می توانید با همین روش مجموع مقادیر مختلف را به دست آورید:

<!DOCTYPE html>
<html>
<body>

<p>Sum of all arguments:</p>
<p id="demo"></p>

<script>
function sumAll() {
  var i;
  var sum = 0;
  for(i = 0; i < arguments.length; i++) {
    sum += arguments[i];
  }
  return sum;
}
document.getElementById("demo").innerHTML = sumAll(1, 123, 500, 115, 44, 88);
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

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

تفاوت by Value و by Reference چیست؟

آرگومان ها از نوع Passed by Value هستند: این مسئله بدین معنی است که تابع تنها مقادیر (value ها) را می شناسد، نه مکان آرگومان ها را. بنابراین اگر تابعی مقدار آرگومانی را تغییر دهد، مقدار اولیه ی آن پارامتر تغییری نمی کند. بگذارید ساده تر بگویم؛ pass by value به معنی پاس دادن خودِ مقدار است. بنابراین اگر متغیری به نام X را به عنوان آرگومان به تابعی دهیم:

<!DOCTYPE html>
<html>
<body>

<p id="OriginalValueOfX"></p>
<p id="NewValueOfX"></p>

<script>
  var x = 10;
  
function passByValue (ValueOfX) {
  ValueOfX++;
  document.getElementById("NewValueOfX").innerHTML = ValueOfX;
}

passByValue(x);
  
  
document.getElementById("OriginalValueOfX").innerHTML = x;

</script>

</body>
</html>

مشاهده ی خروجی در JSBin

در مثال بالا ابتدا یک متغیر به نام x تعریف کردیم و به آن مقدار 10 را دادیم. سپس داخل تابعی به نام passByValue، مقدار x را عوض کرده و یک عدد به آن اضافه کردیم تا مساوی با 11 بشود اما اگر خروجی را ببینید متوجه می شوید که مقدار اصلی x دست نخورده است و هنوز همان 10 می باشد. چرا؟ به این دلیل که آرگومان ها در جاوا اسکریپت از نوع Pass by Value هستند؛ یعنی با متغیر X کاری ندارند بلکه مقدارِ x (یعنی عدد 10) را برمیدارند و عملیات را روی عدد 10 انجام می دهند. بدین صورت، خود متغیر x هیچ تغییری نمی کند.

اشیاء از نوع Passed by Reference هستند: برخلاف آرگومان ها اشیاء از جنس Passed by Reference هستند بنابراین اگر تابعی خصوصیت (property) یک تابع را تغییر دهد، مقدار اصلی خصوصیت نیز تغییر پیدا می کند. به مثال زیر دقت کنید:

<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var person = {
  firstname:"John",
  lastname:"Doe",
  age:50,
  eyecolor:"blue"
};
  
  function changeAge (){
    person.age = 80;
  }
  
  changeAge();

document.getElementById("demo").innerHTML = person.firstname + " is " + person.age + " years old.";
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

به خروجی کد بالا بروید و خط 19 کد (;()changeAge) را حذف کنید. به خروجی نگاه و سپس دوباره این خط را اضافه کنید. میبینید با اجرای تابع، خصوصیت شیء کاملا عوض می شود. Pass by reference یعنی پاس دادنِ ارجاع؛ بنابراین به جای آنکه عدد 50 گرفته شود و به تابع داده شود، خودِ خصوصیت age، که به عدد 50 ارجاع می دهد، به تابع داده می شود.

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

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری جاوا اسکریپت پیشرفته توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما (1 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سارا
10 دی 1398
اشیا از نوع pass by reference هستند درحالی که در مقاله ذکر شده pass by value با تشکر

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

امیر زوارمی
12 دی 1398
سلام دوست عزیز از تذکر شما ممنونم. اشتباه تایپی به زودی اصلاح میشه.

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.