Skip to content

8. توابع

Image

8.1. اسکریپت [func-01]

اسکریپت بررسی می‌کند که پارامترها چگونه به یک تابع ارسال می‌شوند:

  • pass-by-value برای اعداد، رشته‌ها و بولین‌ها؛
  • pass-by-reference برای آرایه‌ها، اشیاء صریح و توابع؛

''use strict';
// حالت ارسال پارامتر تابع
//----------------------- عدد – با مقدار ارسال می‌شود
function doSomethingWithNumber(param) {
  param++;
  console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === count);
}
// کد فراخوانی
let count = 10;
doSomethingWithNumber(count);
console.log("[count outside function]=", count);

// --------------------- رشته – با مقدار ارسال می‌شود
function doSomethingWithString(param) {
  param += " xyz"
  console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === text);
}
// کد فراخوانی
let text = "abcd";
doSomethingWithString(text);
console.log("[text outside function]=", text);

// --------------------- بولین – ارسال توسط مقدار
function doSomethingWithBoolean(param) {
  param = !param;
  console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === bool);
}
// کد تماس
let bool = true;
doSomethingWithBoolean(bool);
console.log("bool [outside function]=", bool);

// --------------------- آرایه - ارسال توسط مرجع
function doSomethingWithArray(param) {
  param.push(1000);
  console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === tab);
}
// کد فراخوانی
const tab = [10, 20, 30];
doSomethingWithArray(tab);
console.log("[tab outside function]=", tab);

// --------------------- شیء – ارسال توسط ارجاع
function doSomethingWithObject(param) {
  param.unePropriétéNouvelle = "xyz";
  console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === obj);
}
// کد فراخوانی
const obj = [10, 20, 30];
doSomethingWithObject(obj);
console.log("[obj outside function]=", obj);

// --------------------- تابع – ارسال توسط مرجع
function doSomethingWithFunction(param) {
  // چیزی نسبتاً عجیب، اما به هر حال کار می‌کند
  param.unePropriétéNouvelle = "xyz";
  console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === f);
}
// کد تماس
const f = x => x + 4;
doSomethingWithFunction(f);
console.log("[f outside function]=", f, f.unePropriétéNouvelle, typeof (f));

اجرا


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\fonctions\func-01.js"
[param inside function]= 11 [type]= number [passage par référence]= false
[count outside function]= 10
[param inside function]= abcd xyz [type]= string [passage par référence]= false
[text outside function]= abcd
[param inside function]= false [type]= boolean [passage par référence]= false
bool [outside function]= true
[param inside function]= [ 10, 20, 30, 1000 ] [type]= object [passage par référence]= true
[tab outside function]= [ 10, 20, 30, 1000 ]
[param inside function]= [ 10, 20, 30, 'unePropriétéNouvelle': 'xyz' ] [type]= object [passage par référence]= true
[obj outside function]= [ 10, 20, 30, 'unePropriétéNouvelle': 'xyz' ]
[param inside function]= x => x + 4 [type]= function [passage par référence]= true
[f outside function]= x => x + 4 xyz function

8.2. اسکریپت [func-02]

اسکریپت زیر نشان می‌دهد که نوع [function] مانند هر نوع دیگری یک نوع داده است و یک متغیر می‌تواند این نوع را داشته باشد. همچنین دو روش تعریف یک تابع را نشان می‌دهد:

  • یکی با استفاده از کلمه کلیدی [function];
  • دیگری با استفاده از نشانه «تیر» =>;

''use strict';
// می‌توانید یک تابع را به یک متغیر اختصاص دهید
const variable1 = function (a, b) {
  return a + b;
};
console.log("typeof(variable1)=", typeof (variable1));
// سپس می‌توان از متغیر به‌عنوان یک تابع استفاده کرد
console.log("variable1(10,12)=", variable1(10, 12));
// تابع را می‌توان با استفاده از نشانه => تعریف کرد
const variable2 = (a, b, c) => {
  return a - b + c;
};
console.log("variable2(10,12,14)=", variable2(10, 12, 14));
// کروشه‌های منحنی اختیاری هستند اگر تنها یک عبارت در بدنه تابع وجود داشته باشد
//این عبارت سپس مقدار بازگشتی تابع است
const variable3 = (a, b, c) => a + b + c;
console.log("variable3(10,12,14)=", variable3(10, 12, 14));

اجرا


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\fonctions\func-02.js"
typeof(variable1)= function
variable1(10,12)= 22
variable2(10,12,14)= 12
variable3(10,12,14)= 36

8.3. اسکریپت [func-03]

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


''use strict';
//پارامترهای یک تابع می‌توانند از نوع [fonction] باشند

// تابع f1
function f1(param1, param2) {
  return param1 + param2 + 10;
}
// تابع f2
function f2(param1, param2) {
  return param1 + param2 + 20;
}
// تابع g با تابع f به‌عنوان پارامتر
function g(param1, param2, f) {
  return f(param1, param2) + 100;
}
// کاربردهای g
console.log(g(0, 10, f1));
console.log(g(0, 10, f2));
// پارامتر واقعی نوع تابع می‌تواند به صورت ارجاعی ارسال شود – شکل ۱
console.log(g(0, 10, (param1, param2) => {
  return param1 + param2 + 30;
}));
// پارامتر واقعی از نوع تابع می‌تواند به صورت ارجاعی ارسال شود – شکل ۲
console.log(g(0, 10, function (param1, param2) {
  return param1 + param2 + 40;
}));

اجرا


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\fonctions\func-03.js"
120
130
140
150

8.4. script [func-04]

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


''use strict';
//یک تابع می‌تواند به‌عنوان یک شیء استفاده شود

//یک پوسته خالی
function f() {

}
// که ویژگی‌ها از خارج به آن اختصاص داده می‌شوند
f.prop1 = "val1";
f.show = function () {
  console.log(this.prop1);
}
// استفاده از f
f.show();

// یک تابع g که به‌عنوان یک کلاس عمل می‌کند
function g() {
  this.prop2 = "val2";
  this.show = function () {
    console.log(this.prop2);
  }
}
// مثال‌سازی تابع با [new]
new g().show();

توضیحات

  • خطوط ۵–۷: بدنه تابع f هیچ خصوصیتی را تعریف نمی‌کند؛
  • خطوط ۹–۱۲: ویژگی‌ها از خارج به تابع `f` اختصاص داده می‌شوند؛
  • خط ۱۴: استفاده از تابع (شیء) `f`. توجه کنید که ما `[f()]` را نمی‌نویسیم، بلکه به سادگی `[f]` را می‌نویسیم. این نشانه‌گذاری برای یک شیء است؛
  • خطوط ۱۷–۲۲: تابع [g] طوری تعریف شده است که گویی یک کلاس با خواص و متدها است؛
  • خط ۲۴: تابع [g] توسط [new g()] نمونه سازی می‌شود؛

نتایج اجرا


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-00.js"
val1
val2

ES6 مفهوم کلاس را معرفی کرد، که اکنون به ما امکان می‌دهد از استفاده از توابع برای ایجاد کلاس‌ها اجتناب کنیم.

8.5. اسکریپت [func-05]

اسکریپت [func-05] استفاده از یک عملگر به نام [rest operator] را نشان می‌دهد:


''use strict';
// اپراتور rest
function f(arg1, ...otherArgs) {
  // آرگومان اول
  console.log("arg1=", arg1);
  // سایر آرگومان‌ها
  let i = 0;
  otherArgs.forEach(element => {
    console.log("otherArguments[", i, "]=", element);
    i++;
  });
}

//فراخوانی
f(1, "deux", "trois", { x: 2, y: 3 })
  • خط ۳: نشانه [...otherArgs] به این معنی است که با فراخوانی‌ای به شکل f(param1, param2, param3)، خواهیم داشت خط ۳:
    • arg1=param1
    • otherArgs=[param2, param3]. بنابراین [otherArgs] آرایه‌ای است که شامل تمام پارامترهای واقعی ارسال‌شده به [param1] می‌باشد؛

نتایج برنامه به شرح زیر است:

1
2
3
4
arg1= 1
otherArguments[ 0 ]= deux
otherArguments[ 1 ]= trois
otherArguments[ 2 ]= { x: 2, y: 3 }