تایپ Function در جاوااسکریپت

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

مقدمه‌ای بر تایپ Function جاوااسکریپت

در جاوااسکریپت، همه توابع یک آبجکت محسوب می‌شوند که نمونه‌هایی از تایپ Function هستند. از آنجایی که توابع، آبجکت به‌شمار می‌آیند مانند سایر آبجکت‌ها دارای ویژگی‌ها و روش‌هایی نیز می‌باشند.

ویژگی‌های توابع

هر تابع دو ویژگی مهم دارد:

length
lengthو
prototype
prototype.

  • ویژگی
    length
    length تعداد آرگومان‌های نام‌گذاری شده که در تعریف تابع مشخص شده‌اند را تعیین می‌کند.
  • ویژگی
    prototype
    prototype به آبجکت تابع واقعی اشاره می‌کند.

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function add(x, y) {
return x + y;
}
console.log(add.length); // 2
console.log(add.prototype); // Object{}
function add(x, y) { return x + y; } console.log(add.length); // 2 console.log(add.prototype); // Object{}
function add(x, y) {
    return x + y;
}

console.log(add.length); // 2
console.log(add.prototype); // Object{}

تابع

add()
add()دو آرگومان x و y را دریافت می‌کند. بنابراین، ویژگی
length
lengthمقدار ۲ را برمی‌گرداند.

new.target

به طور معمول، ما یک تابع را به صورت عادی و به شکل زیر فراخوانی می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let result = add(10,20);
console.log(result); // 30
let result = add(10,20); console.log(result); // 30
let result = add(10,20);
console.log(result); // 30

همچنین می‌توانیم یک تابع را با کلمه کلیدی

new
newبه عنوان تابع سازنده فراخوانی کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let obj = new add(10,20);
let obj = new add(10,20);
let obj = new add(10,20);

ES6 شبه خاصیت new.target را معرفی کرده و به ما این امکان را می‌دهد تا بتوانیم تشخیص دهیم که آیا یک تابع معمولی یا تابع سازنده با استفاده از عملگر

new
new فراخوانی شده است یا خیر.

اگر تابعی به طور معمولی فراخوانی شود، new.target در این صورت

undefined
undefinedاست. با این حال، اگر تابع با استفاده از کلمه کلیدی
new
new به عنوان سازنده فراخوانی شود، new.target رفرنسی را به تابع سازنده برمی‌گرداند. به عنوان مثال:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function add(x, y) {
console.log(new.target);
return x + y;
}
let result = add(10, 20);
let obj = new add(10, 20);
function add(x, y) { console.log(new.target); return x + y; } let result = add(10, 20); let obj = new add(10, 20);
function add(x, y) {
  console.log(new.target);
  return x + y;
}

let result = add(10, 20);
let obj = new add(10, 20);

خروجی کد به صورت زیر است:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
undefined
[Function: add]
undefined [Function: add]
undefined
[Function: add]

با استفاده از new.target می‌توانیم نحوه فراخوانی یک تابع را نیز کنترل کنیم.

به عنوان مثال، برای جلوگیری از فراخوانی تابع

add()
add()به عنوان سازنده با استفاده از کلمه کلیدی
new
new، می‌توانیم با بررسی new.target به شکل زیر خطا ایجاد کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function add(x, y) {
if (new.target) {
throw 'The add function cannot be called as a constructor';
}
return x + y;
}
let obj = new add(10, 20);
console.log(obj);
function add(x, y) { if (new.target) { throw 'The add function cannot be called as a constructor'; } return x + y; } let obj = new add(10, 20); console.log(obj);
function add(x, y) {
  if (new.target) {
    throw 'The add function cannot be called as a constructor';
  }
  return x + y;
}

let obj = new add(10, 20);
console.log(obj);

متدهای فانکشن: apply، call و bind

یک آبجکت تابع سه متد مهم دارد: 

apply()
apply(),
call()
call() و
bind()
bind().در ادامه هر کدام از این متدها را بررسی خواهیم کرد.

متدهای ()apply و ()call

متدهای

apply()
apply()و
call()
call()یک تابع با مقدار
this
thisو آرگومان‌های داده شده را فراخوانی می‌کنند.

تفاوت بین این دو متد در این است که ما باید آرگومان‌ها را به عنوان یک آبجکت آرایه مانند به

apply()
apply()منتقل کنیم، در حالی که در تابع
call()
call()آرگومان‌ها را به صورت جداگانه ارسال می‌کنیم. مثلا:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let cat = { type: 'Cat', sound: 'Meow' };
let dog = { type: 'Dog', sound: 'Woof' };
const say = function (message) {
console.log(message);
console.log(this.type + ' says ' + this.sound);
};
say.apply(cat, ['What does a cat say?']);
say.apply(dog, ['What does a dog say?']);
let cat = { type: 'Cat', sound: 'Meow' }; let dog = { type: 'Dog', sound: 'Woof' }; const say = function (message) { console.log(message); console.log(this.type + ' says ' + this.sound); }; say.apply(cat, ['What does a cat say?']); say.apply(dog, ['What does a dog say?']);
let cat = { type: 'Cat', sound: 'Meow' };
let dog = { type: 'Dog', sound: 'Woof' };

const say = function (message) {
  console.log(message);
  console.log(this.type + ' says ' + this.sound);
};

say.apply(cat, ['What does a cat say?']);
say.apply(dog, ['What does a dog say?']);

خروجی به شکل زیر است:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
What does a cat sound?
Cat says Meow
What does a dog sound?
Dog says Woof
What does a cat sound? Cat says Meow What does a dog sound? Dog says Woof
What does a cat sound?
Cat says Meow
What does a dog sound?
Dog says Woof

در این مثال، ابتدا دو آبجکت

cat
catو
dog
dogرا با دو ویژگی تعریف می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let cat = { type: 'Cat', sound: 'Meow' };
let dog = { type: 'Dog', sound: 'Woof' };
let cat = { type: 'Cat', sound: 'Meow' }; let dog = { type: 'Dog', sound: 'Woof' };
let cat = { type: 'Cat', sound: 'Meow' };
let dog = { type: 'Dog', sound: 'Woof' };

در مرحله دوم تابع

say()
say()را تعریف می‌کنیم که یک آرگومان می‌گیرد:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const say = function (message) {
console.log(message);
console.log(this.type + ' says ' + this.sound);
};
const say = function (message) { console.log(message); console.log(this.type + ' says ' + this.sound); };
const say = function (message) {
  console.log(message);
  console.log(this.type + ' says ' + this.sound);
};

سپس در مرحله سوم تابع

say()
say()را توسط متد
apply()
apply()فراخوانی می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
say.apply(cat, ['What does a cat say?']);
say.apply(cat, ['What does a cat say?']);
say.apply(cat, ['What does a cat say?']);

در این مثال اولین آرگومان متد

apply()
apply()آبجکت
cat
catاست. بنابراین
this
thisدر تابع
say()
say() به آبجکت
cat
cat اشاره می‌کند.

در مرحله چهارم تابع

say()
say()را فراخوانی می‌کنیم و آبجکت
dog
dogرا به آن ارسال می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
say.apply(dog, ['What does a dog say?']);
say.apply(dog, ['What does a dog say?']);
say.apply(dog, ['What does a dog say?']);

اما اینجا

this
this در تابع
say()
say() به آبجکت
dog
dog اشاره می‌کند.

متد

call()
call()مانند متد
apply()
apply()است اما فقط روشی که آرگومان‌ها را به تابع ارسال می‌کنیم متفاوت است:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
say.call(cat, 'What does a cat say?');
say.call(dog, 'What does a dog say?');
say.call(cat, 'What does a cat say?'); say.call(dog, 'What does a dog say?');
say.call(cat, 'What does a cat say?');
say.call(dog, 'What does a dog say?');

متد ()bind

bind()
bind()یک نمونه تابع جدید ایجاد می‌کند که این مقدار به آبجکتی که ما ارائه می‌کنیم محدود می‌شود. مثلا:

ابتدا یک آبجکت به نام

car
carتعریف می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let car = {
speed: 5,
start: function() {
console.log('Start with ' + this.speed + ' km/h');
}
};
let car = { speed: 5, start: function() { console.log('Start with ' + this.speed + ' km/h'); } };
let car = {
    speed: 5,
    start: function() {
        console.log('Start with ' + this.speed + ' km/h');
    }
};

سپس آبجکت دیگری به نام

aircraft
aircraftرا تعریف می‌کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let aircraft = {
speed: 10,
fly: function() {
console.log('Flying');
}
};
let aircraft = { speed: 10, fly: function() { console.log('Flying'); } };
let aircraft = {
    speed: 10,
    fly: function() {
        console.log('Flying');
    }
};

aircraft
aircraftمتد
start()
start()ندارد. برای این که بتوانیم
aircraft
aircraft را راه‌اندازی کنیم، می‌توانیم به کمک
bind()
bind()از متد
start()
start()آبجکت
car
carاستفاده کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
let taxiing = car.start.bind(aircraft);
let taxiing = car.start.bind(aircraft);
let taxiing = car.start.bind(aircraft);

در این عبارت، مقدار

this
thisرا در متد
start()
start()آبجکت
car
carبه آبجکت
aircraft
aircraftتغییر می‌دهیم. متد
bind()
bind()تابع جدیدی را برمی‌گرداند که به متغیر
taxiing
taxiingاختصاص داده شده است.

اکنون می‌توانیم متد

start()
start()را از طریق متغیر
taxiing
taxiingفراخوانی کنیم:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
taxiing();
taxiing();
taxiing();

در این صورت پیغام زیر را خواهیم دید:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Start with 10 km/h
Start with 10 km/h
Start with 10 km/h

همانطور که می‌بینید، متد

bind()
bind()یک تابع جدید ایجاد می‌کند که می‌توانیم بعداً آن را اجرا کنیم در حالی که متد
call()
call()بلافاصله تابع را اجرا می‌کند. همین موضوع تفاوت اصلی بین متدهای
bind()
bind()و
call()
call()است.

از نظر فنی آبجکت

aircraft
aircraftمتد
start()
start()آبجکت
car
carرا از طریق متد
apply()
apply(),
call()
call() و
bind()
bind() قرض می‌گیرد. به همین دلیل است که متدهای
apply()
apply(),
call()
call() و
bind()
bind()نیز به عنوان توابع borrowing شناخته می‌شوند.

جمع‌بندی

  • همه توابع نمونه‌هایی از تایپ Function هستند، آبجکت‌هایی که دارای ویژگی‌ها و متدهای مربوط به خود می‌باشند
  • هر تابع دو ویژگی مهم دارد:
    length
    lengthو
    prototype
    prototype
  • هر تابع دارای سه متد مهم است:
    apply()
    apply(),
    call()
    call() و
    bind()
    bind()

دیدگاه‌ها:

mostafa mehrabi

مرداد 19, 1401  در  8:23 ب.ظ

دقیق
واضح
و کامل بود
ممنون🎉

افزودن دیدگاه جدید