آبجکت Function ECMAScript (کلاس)

توابع ECMAScript در واقع اشیای کامل هستند.

شیء Function (کلاس)

ممکن است یکی از جذاب‌ترین جنبه‌های ECMAScript این باشد که توابع در واقع اشیای کامل هستند.

کلاس Function می‌تواند هر توابعی که توسعه‌دهنده تعریف کرده است را نشان دهد.

قانون نویسی توابع مستقیم با استفاده از Function کلاس به صورت زیر است:

var function_name = new function()arg1, arg2, ... , argN, function_body)

در این فرم، هر arg همه یک پارامتر دارند، پارامتر آخر بدنه تابع (کدی که باید اجرا شود) است. این پارامترها باید رشته باشند.

به این تابع یادآوری می‌کنید؟

function sayHi(sName, sMessage) {
  alert("Hello " + sName + sMessage);
}

می‌توان آن را به این صورت نیز تعریف کرد:

var sayHi 
= 
new Function("sName", "sMessage", "alert("Hello " + sName + sMessage)");

اگرچه به دلیل رشته‌ها، این فرم ممکن است کمی دشوار باشد، اما به درک این که تابع‌ها تنها نوعی ارجاع هستند و رفتارشان مشابه تابع‌هایی است که با استفاده از Function کلاس به صورت واضح ایجاد می‌شوند، کمک می‌کند.

لطفاً به این مثال زیر توجه کنید:

function doAdd(iNum) {
  alert(iNum + 20);
}
function doAdd(iNum) {
  alert(iNum + 10);
}
doAdd(10);	// خروجی "20"

همانطور که می‌دانید، دومین تابع اولین تابع را پرکرده است، به طوری که doAdd(10) "20" را خروجی داد، نه "30".

اگر این کد را به این شکل بازنویسی کنید، مفهوم واضح‌تر می‌شود:

var doAdd = new Function("iNum", "alert(iNum + 20)");
var doAdd = new Function("iNum", "alert(iNum + 10)");
doAdd(10);

لطفاً این کد را مشاهده کنید، به وضوح، مقدار doAdd به یک اشاره‌گر به یک شیء مختلف تغییر کرده است. نام تابع تنها یک ارجاع به شیء تابع است و مانند سایر شیءها عمل می‌کند. حتی می‌توان دو متغیر را به یک تابع مشابه اشاره داد:

var doAdd = new Function("iNum", "alert(iNum + 10)");
var alsodoAdd = doAdd;
doAdd(10);	// خروجی "20"
alsodoAdd(10);	// خروجی "20"

در اینجا، متغیر doAdd به عنوان یک تابع تعریف شده است، سپس alsodoAdd به عنوان یک اشاره‌گر به همان تابع اعلام شده است. با استفاده از هر دو متغیر می‌توان کد تابع را اجرا کرد و نتایج مشابهی - "20" - را دریافت کرد. بنابراین، اگر نام تابع فقط به یک متغیر اشاره کند، آیا می‌توان تابع را به عنوان پارامتر به یک تابع دیگر ارسال کرد؟ پاسخ مثبت است!

function callAnotherFunc(fnFunction, vArgument) {
  fnFunction(vArgument);
}
var doAdd = new Function("iNum", "alert(iNum + 10)");
callAnotherFunc(doAdd, 10);	// خروجی "20"

در مثال بالا، callAnotherFunc() دو پارامتر دارد - توابعی که باید فراخوانی شود و پارامترهایی که به آن فرستاده می‌شوند. این کد تابع doAdd() را به callAnotherFunc() می‌فرستد، پارامتر 10 است و خروجی "20" دارد.

توجه داشته باشید:با اینکه می‌توان از ساختار Function برای ایجاد توابع استفاده کرد، اما بهتر است از آن استفاده نکنید، زیرا ایجاد توابع با استفاده از آن بسیار کندتر از روش‌های سنتی است. با این حال، همه توابع باید به عنوان نمونه‌هایی از موضوع Function در نظر گرفته شوند.

ویژگی length موضوع Function

همانطور که قبلاً ذکر شد، توابع نوع ارجاعی هستند، بنابراین آنها نیز ویژگی‌ها و روش‌ها دارند.

ویژگی length تعریف شده توسط ECMAScript، تعداد پارامترهای مورد انتظار تابع را بیان می‌کند. به عنوان مثال:

function doAdd(iNum) {
  alert(iNum + 10);
}
function sayHi() {
  alert("Hi");
}
alert(doAdd.length);	// خروجی "1"
alert(sayHi.length);	// خروجی "0"

تابع doAdd() یک پارامتر تعریف کرده است، بنابراین length آن 1 است؛ sayHi() هیچ پارامتری تعریف نکرده است، بنابراین length آن 0 است.

به یاد داشته باشید که ECMAScript می‌تواند تعداد نامحدودی از پارامترها را پذیرا باشد (حداکثر 25 عدد)، که در فصل "مقدمه به توابع" توضیح داده شده است. ویژگی length فقط به عنوان یک راه آسان برای مشاهده تعداد پارامترهای پیش‌فرض پیشنهاد شده است.

روش‌های موضوع Function

موضوع Function نیز مانند تمام موضوعات دیگر، روش‌های valueOf() و toString() مشترک دارد. این دو روش همیشه کد منبع تابع را برمی‌گردانند که در حالت调试 بسیار مفید است. به عنوان مثال:

function doAdd(iNum) {
  alert(iNum + 10);
}
document.write(doAdd.toString());

این کد متن تابع doAdd() را چاپ می‌کند.آزمایش کنید!