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

تابع Declaration : در این مورد یک تابع به عنوان یک عبارت جداگانه تعریف می‌شود :

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

تابع Expression : در این مورد یک تابع در داخل یک عبارت دیگر تعریف می‌شود :

// Function Expression
let sum = function(a, b) {
  return a + b;
};

یک Function Expression زمانی که اجرا به آن می‌رسد ایجاد شده و سپس بعد از آن قابل استفاده است اما Function Declaration متفاوت است.

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

sayHi(&quotJohn&quot); // Hello, John

function sayHi(name) {
  alert( `Hello, ${name}` );
}

اما در مورد Function Expression این مورد صحیح نیست :

sayHi(&quotJohn&quot); // error!

let sayHi = function(name) {  // (*) no magic any more
  alert( `Hello, ${name}` );
};

در مورد Function Declaration ها بلاکی که تابع در آن تعریف می‌شود اهمیت دارد و در خارج از آن بلاک نمی‌توان به تابع دسترسی داشت برای مثال :

let age = prompt(&quotWhat is your age?&quot, 18);

// conditionally declare a function
if (age < 18) {

  function welcome() {
    alert(&quotHello!&quot);
  }

} else {

  function welcome() {
    alert(&quotGreetings!&quot);
  }

}

// ...use it later
welcome(); // Error: welcome is not defined


در مثال فوق در فراخوانی تابع welcome با خطا روبرو می‌شویم و این به این خاطر است که Function Declaration ها تنها در بلاک کدی که تعریف شده اند قابل استفاده اند. مثالی دیگر در این باره :

let age = 16; // take 16 as an example

if (age < 18) {
  welcome();               // \   (runs)
                           //  |
  function welcome() {     //  |
    alert(&quotHello!&quot);       //  |  Function Declaration is available
  }                        //  |  everywhere in the block where it's declared
                           //  |
  welcome();               // /   (runs)

} else {

  function welcome() {     //  for age = 16, this &quotwelcome&quot is never created
    alert(&quotGreetings!&quot);
  }
}

// Here we're out of curly braces,
// so we can not see Function Declarations made inside of them.

welcome(); // Error: welcome is not defined

همانطور که مشخص است دو فراخوانی اول تابع صحیح هستند اما فراخوانی سوم با خطا روبرو می شود.

در این مورد برای صحیح کار کردن مثال فوق می توان از Function Expression به شکل زیر استفاده کرد :
let age = prompt(&quotWhat is your age?&quot, 18);

let welcome;

if (age < 18) {

  welcome = function() {
    alert(&quotHello!&quot);
  };

} else {

  welcome = function() {
    alert(&quotGreetings!&quot);
  };

}

welcome(); // ok now

مثال فوق را با عملگر شرطی سه تایی می توان به صورت زیر بازنویسی کرد :

let age = prompt(&quotWhat is your age?&quot, 18);

let welcome = (age < 18) ?
  function() { alert(&quotHello!&quot); } :
  function() { alert(&quotGreetings!&quot); };

welcome(); // ok now