درود دوستان! می‌خوایم یکی از مهمترین ویژگی‌هایی که از ES6 به جاوااسکریپت اضافه شده رو بررسی کنیم: Arrow Function ها.

ما توی دوره «آموزش جاوااسکریپت به زبان ساده» با این توابع آشنا شدیم. توی این قسمت می‌خوایم مقداری تخصصی‌تر با اونها آشنا بشیم. توی این قسمت یاد می‌گیریم که:

 

توی این پست از کلمه مخفف AF بجای Arrow Function استفاده میشه.

 

AF چیه؟

این توابع یک راه کوتاه‌تر برای داشتن Function Expression ها به حساب میان. در واقع این توابع نسخه‌ی جمع و جور شدهٔ توابع معمولی هستن. نحوه نوشتن اونها به صورت زیر هست:

() => "Hello!";

همونطور که گفتیم، AF ها نوعی Function Expression هستن. پس برای اینکه مثل یک تابع قابل استفاده باشن، اونها رو نسبت می‌دیم به یک متغیر:

const sayHello = <<() => "Hello!">>;

alert(sayHello());

اگه بخوایم از توابع معمولی استفاده کنیم، کد بالا به صورت زیر در میاد:

function sayHello() {
    return "Hello!";
}

سادگی استفاده از AF ها هنگام استفاده از توابع Callback بیشتر مشخص میشه:

const numbers = [1, 2, 3];

const dup = numbers.map(<<num => num * 2>>);

alert(dup); // 2, 4, 6

 

چطوری پارامتر پاس بدیم؟

نحوه‌ی پارامتر دادن به یک AF بصورت زیر هست:

() => ...
param1 => ...
(param1, param2, ..., paramN) => ...

توی کد بالا:

  • خط ۱ هیچ پارامتری نداریم. برای تابعی که هیچ پارامتری نداره باید از یک پرانتز باز و بسته استفاده کنیم
  • خط ۲ تابعی هست با یک پارامتر. اگه تابع فقط یک پارامتر داره قرار دادن پرانتز دور اون اختیاری هست
  • خط ۳ تابعی هست با دو یا چند پارامتر که باید اونها رو داخل پرانتز قرار بدیم

 

خروجی تابع رو چطوری مشخص کنیم؟

عبارتی که جلوی => قرار می‌گیره بصورت خودکار return میشه:

const give2 = () => 2;

alert(give2() + 2); // 4

اگه عبارت جلوی => طولانی هست می‌تونیم از پرانتز استفاده کنیم و اون عبارت رو ببریم توی یک خط جدا:

const welcome = user => <<(>>
  `Welcome ${user}. This is a long text.
So I moved it into a separate line.
Hope you enjoy it.`
<<)>>

alert(welcome("Emily"));

اگه بدنه‌ی تابع چند خطی باشه، باید بدنه رو درون بلاک {...} قرار بدیم و برخلاف کدهای بالا باید بصورت دستی return کنیم:

const give2 = () => {
   const x = 1;
   const y = 4;
   
   return x * y / 2;
}

alert(give2() + 2);

 

عملگر Rest و پارامترها

پارامتر Rest برای این توابع قابل استفاده هست:

const echo = (...numbers) => {
    alert(numbers);
}

echo(1, 2, 3) // 1,2,3

 

تعریف کردن پارامترهای پیشفرض

پارامترها پیشفرض هم برای این توابع قابل استفاده هست:

const greeting = (user, type = "Hello") => {
  alert(`${type} ${user}!`);
};

greeting("Emily");            // Hello Emily!
greeting("Mario", "Welcome"); // Welcome Mario!

 

استفاده از کلمه‌کلیدی new برای AF ها

توی دوره «آموزش جاوااسکریپت به زبان ساده» با توابع Constructor آشنا شدیم و دیدیم که چطوری با اونها می‌تونیم آبجکت‌هایی داشته باشیم که از یک طرح و الگو ساخته شدن. ما کار ساختن آبجکت‌ها رو با استفاده از کلمه‌کلیدی new انجام می‌دادیم. نکته‌ای که باید در نظر داشته باشیم اینه که کلمه‌کلیدی new فقط برای توابع معمولی استفاده میشه و این کار برای AF ها شدنی نیست:

const Person = name => {
    this.name = name;
}

const a = new Person('Josh');
// TypeError: Person is not a constructor

به عبارت دیگه، فقط توابع معمولی می‌تونن به عنوان توابع Constructor در نظر گرفته بشن و AF ها این قابلیت رو ندارن.

 

مقدار this

یکی از نکات مهمی که باید در نظر داشته باشیم اینه که مقدار this توی توابع معمولی با مقدار اون توی AF فرق می‌کنه.

AF ها هیچ مقداری به this نمیدن و مقدار this توی این توابع به قسمتی از کد (اسکوپ) اشاره می‌کنه که ‌‌AF توی اون تعریف شده. بدون در نظر گرفتن اینکه تابع کجا تعریف شده و چه جوری داره استفاده میشه:

var name = "Covey";

const person = {
  name: "Stephen",
  getName: () => {
    alert(this.name);
  }
}

person.getName(); // Covey

const myGetName = person.getName;
myGetName(); // Covey

همونطور که می‌بینیم توی خط ۱۰ و ۱۳ خروجی به اون name اشاره می‌کنه که اول کد هست. چرا؟ 🤔  چون گفتیم مقدار this توی AF به قسمتی از کد اشاره می‌کنه که AF توی اون تعریف شده. الان تابع getName توی person تعریف شده. اسکوپ مربوط به person کجاست؟ اسکوپ سراسری. پس this به این اسکوپ اشاره می‌کنه.

 

آبجکت arguments

توی توابع AF آبجکت arguments وجود نداره:

const stp = () => {
  alert(arugments);
}

stp(1, 2, 4); // ReferenceError: arugments is not defined

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

const stp = (...args) => {
    alert(args);
}

stp(1, 2, 4); // 1,2,4

برای اطلاع بیشتر از آبجکت arguments اینجا رو بخونید.

 

پراپرتی Prototype

برای AFها پراپرتی prototype وجود نداره و undefined هست:

function person() {}
console.log(person.prototype); // Object { … }

var person = () => {}
console.log(person.prototype); // undefined

 

خب این قسمت هم به پایان رسید. نکته‌ای که باید درنظر داشته باشیم اینه که قبل از استفاده از یک ابزار، ویژگی و ... ابتدا باید خیلی خوب رفتارهای اون رو بشناسیم. Arrow Function ها با همه‌ی ویژگی‌های خوبی که دارن، به عنوان یک جایگزین ۱۰۰٪ برای توابع معمولی نیستن و توی شرایط مختلف حتماً هر دو نوع تابع استفاده میشه. چیزی که باید بدونیم درک تفاوت‌ها و کارایی اونهاست. روزتون خوش ✌️😉

 

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

www.w3schools.com/js/js_arrow_function.asp