کارکرد

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

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

function myFunction() {
   console.log( "This is my function." );
};

تابعی که به عنوان ویژگی یک شی تعریف می شود معمولاً "روش" نامیده می شود. همانند متغیرهای اعلام شده با استفاده از var ، اعلان‌های تابعی که خارج از یک تابع محصور شده است به عنوان متد به شی سراسری اضافه می‌شوند.

اعلامیه های عملکرد

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

function myFunction() {
   console.log( "This is my function." );
};

myFunction();
> "This is my function."

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

"use strict";
{
    myFunction();
    function myFunction() {
        console.log( "This is my function." );
    };
}
> "This is my function."

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

function myFunction() {
    function myNestedFunction() {
        console.log( "This is my nested function." );
    }
    myNestedFunction();
};

myFunction();
> "This is my nested function."

myNestedFunction();
>Uncaught ReferenceError: myNestedFunction is not defined

در حالت دقیق ، اعلان‌های تابع به نزدیک‌ترین بلوک محصور خود، مانند متغیرهایی که با استفاده از let یا const اعلام می‌شوند، محدوده می‌شوند:

"use strict";
{
    function myFunction() {
        console.log( "This is my function." );
    };
}

myFunction();
> Uncaught ReferenceError: myFunction is not defined
فراخوانی تابع

همانند متغیرها، شناسه مورد استفاده هنگام اعلام یک تابع به عنوان یک نام نمادین برای یک مقدار عمل می کند. ارجاع یک تابع با شناسه به تنهایی فقط شی تابع را برمی گرداند و تابعی را که شامل آن است اجرا نمی کند:

function myFunction() {
   console.log( "This is my function." );
};

myFunction;
> myFunction() {
   console.log( "This is my function." );
}

برای اجرای کد در داخل بدنه تابع، تابع را با دنبال کردن نام تابع با یک جفت پرانتز همسان فراخوانی (یا فراخوانی ) کنید:

function myFunction() {
    console.log( "My function has been executed." );
}

myFunction();
> "My function has been executed."

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

function myFunction( myParameter ) {
   console.log( `The value is: ${ myParameter }.` );
};

myFunction( "this string" );
> "The value is: this string."

اگر یک آرگومان مورد انتظار حذف شود، پارامتر حاصل حاوی یک مقدار undefined است، زیرا پارامتر به بدنه تابع اعلان می شود اما با یک مقدار اولیه نمی شود:

function myFunction( myParameter ) {
   console.log( `The value is: ${ myParameter }.` );
};

myFunction();
> "The value is: undefined."

می‌توانید مقادیر پارامترهای پیش‌فرض را با مقداردهی اولیه آن‌ها به همان روشی که یک متغیر را مقداردهی اولیه می‌کنید، تنظیم کنید: یک عملگر انتساب ( = ) و به دنبال آن یک مقدار. اگر بعداً یک آرگومان برای آن تابع مشخص کنید، آن مقدار جدید مقدار پیش فرض را لغو می کند:

function myFunction( myParameter = "omitted" ) {
   console.log( `The value is: ${ myParameter }.` );
};

myFunction( "this string" );
> "The value is: this string."

myFunction();
> "The value is: omitted."

بدنه یک تابع غیر پیکانی همچنین به یک شی arguments مانند با نمایه صفر دسترسی دارد که حاوی مقادیری است که به عنوان آرگومان ارسال می شود، خواه تعریف تابع پارامترها را مشخص کند یا نه:

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

myFunction( 3, true, "My string" );
> Arguments { 0: 3, 1: true, 2: "My string", … }
توابع متغیر

شیء arguments به شما امکان می‌دهد توابع متغیر اساسی ایجاد کنید، که می‌توانند تعداد متغیری از آرگومان‌ها را بپذیرند:

function myFunction() {
    let result = "";
    for (let i = 0; i < arguments.length; i++) {
        result += arguments[i] + " - ";
    }
    console.log( result );
};

myFunction( "My first string", "My second string", "my third string" );\
> "My first string - My second string - my third string - "

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

function myFunction( mySeparator, ...myStrings ) {
  console.log( myStrings.join( mySeparator ) );
};

myFunction( " - ", "My first string", "My second string", "my third string" );
> "My first string - My second string - my third string"

بر خلاف اتصال parameter ، نحو پارامتر استراحت همانطور که انتظار می رود با پارامترهای تابع پیکان کار می کند:

function myOuterFunction() {
    let myInnerArrowFunction = ( ...myParams ) => {
        console.log( myParams[ 0 ] );
    }
    myInnerArrowFunction( true );
};

myOuterFunction( false );
> true

let myArrowFunction = ( ...myParams ) => {
    console.log( myParams[ 0 ] );
};

myArrowFunction( true );
> true`
``