الدوال السهمية في لغة JavaScript


الدوال السهمية في لغة JavaScript

يا هلا فيك! اليوم بنتكلم عن واحدة من أحلى الميزات في JavaScript الحديثة: الدوال السهمية (Arrow Functions). ليش حلوة؟ لأنها تخلي الكود أقصر، وأحياناً أوضح، وبتفهم الفرق الجوهري في طريقة تعاملها مع this.

1. ليه الدوال السهمية؟ (Why Arrow Functions?)

قبل ES6، كنا نكتب الدوال بالطريقة الكلاسيكية:


// دالة عادية (Traditional Function)
function greet(name) {
    return 'مرحباً، ' + name + '!';
}

const greetAnon = function(name) {
    return 'مرحباً، ' + name + '!';
};

الدوال السهمية جات عشان تختصر السنتاكس وتخلي الكود أنظف، خصوصاً لما تكون الدوال قصيرة أو تستخدم كـ callbacks.

2. السنتاكس الأساسي (Basic Syntax)

أ. بدون بارامترات (No Parameters)


const sayHello = () => {
    return 'أهلاً وسهلاً!';
};
// أو لو سطر واحد (Implicit return):
const sayHelloShort = () => 'أهلاً وسهلاً!';
console.log(sayHelloShort()); // أهلاً وسهلاً!

ب. بارامتر واحد (One Parameter)

لو عندك بارامتر واحد، ممكن تستغني عن الأقواس حول البارامتر.


const greetPerson = name => {
    return مرحباً بك يا ${name}!;
};
// أو أقصر:
const greetPersonShort = name => مرحباً بك يا ${name}!;
console.log(greetPersonShort('علي')); // مرحباً بك يا علي!

ج. أكثر من بارامتر (Multiple Parameters)

هنا لازم تحط الأقواس حول البارامترات.


const add = (a, b) => {
    return a + b;
};
// أو أقصر:
const addShort = (a, b) => a + b;
console.log(addShort(5, 3)); // 8

د. إرجاع كائن (Returning an Object)

لو بترجع كائن مباشرةً بدون return صريحة، لازم تحط الكائن بين أقواس عشان ما يفهمها JavaScript إنها بلوك كود.


const createUser = (name, age) => ({ name: name, age: age });
console.log(createUser('سارة', 30)); // { name: 'سارة', age: 30 }
ملاحظة سريعة: لما يكون جسم الدالة سطر واحد فقط، تقدر تحذف الأقواس المعقوفة {} وكلمة return. وهذا يسمى "Implicit Return" أو الإرجاع الضمني.

3. الفرق الجوهري: التعامل مع this (The this Context)

هذي هي أهم نقطة لازم تفهمها عن الدوال السهمية. الدوال العادية في JavaScript تحدد قيمة this بناءً على كيفية استدعائها. لكن الدوال السهمية ما تحدد قيمة this الخاصة بها. بدلاً من ذلك، هي تورث قيمة this من النطاق الأب (Lexical Scope) اللي تم تعريفها فيه.


const person = {
    name: 'أحمد',
    // دالة عادية
    greetRegular: function() {
        setTimeout(function() {
            // هنا this تشير إلى الكائن window أو undefined في الوضع الصارم
            console.log('مرحباً يا ' + this.name);
        }, 100);
    },
    // دالة سهمية
    greetArrow: function() {
        setTimeout(() => {
            // هنا this تورث من النطاق الأب (greetArrow)،
            // وبالتالي تشير إلى الكائن person
            console.log('مرحباً يا ' + this.name);
        }, 100);
    }
};

person.greetRegular(); // بعد 100ms: مرحباً يا (undefined/empty)
person.greetArrow();  // بعد 100ms: مرحباً يا أحمد

شوف الفرق؟ في greetRegular، الـ this داخل الـ setTimeout تغيرت. لكن في greetArrow، الـ this ظلت تشير إلى الكائن person لأن الدالة السهمية ورثتها من الدالة الأب greetArrow (التي هي نفسها method على person).

خلاصة: الدوال السهمية تحل مشكلة شائعة جداً في JavaScript وهي "فقدان this" داخل الـ callbacks أو الدوال المتداخلة.

4. متى لا تستخدم الدوال السهمية؟ (When NOT to Use Arrow Functions?)

صحيح إنها رائعة، بس مو لكل الحالات. فيه أماكن الأفضل تستخدم فيها الدوال العادية:

أ. كـ methods في الكائنات (Object Methods)

لو استخدمت دالة سهمية كـ method مباشرةً في كائن، الـ this راح تشير إلى النطاق الأب للكائن (غالباً window أو undefined في الـ module scope)، وليس إلى الكائن نفسه.


const car = {
    model: 'BMW',
    // هذا خطأ! this هنا ما راح تشير للـ car
    start: () => {
        console.log(بدأت ${this.model}); // هذا راح يكون undefined
    },
    // الطريقة الصحيحة
    stop: function() {
        console.log(توقفت ${this.model});
    }
};

car.start(); // بدأت undefined
car.stop();  // توقفت BMW

ب. كـ constructors (الدوال البانية)

الدوال السهمية ما تقدر تستخدمها كـ constructors (مع كلمة new). راح تعطيك خطأ.


const MyClass = () => {};
// new MyClass(); // TypeError: MyClass is not a constructor

ج. مع الـ arguments object

الدوال السهمية ما عندها الـ arguments object الخاص فيها. لو احتجت الوصول للـ arguments، استخدم دالة عادية أو الـ Rest Parameters (...args).


const showArgsRegular = function() {
    console.log(arguments); // [1, 2, 3]
};
showArgsRegular(1, 2, 3);

const showArgsArrow = (...args) => { // استخدم Rest Parameters بدلاً من arguments
    console.log(args); // [1, 2, 3]
};
showArgsArrow(1, 2, 3);

// const showArgsArrowBad = () => {
//     console.log(arguments); // ReferenceError: arguments is not defined
// };
// showArgsArrowBad(1, 2, 3);

5. خلاصة (Conclusion)

الدوال السهمية أداة قوية جداً في جعبة أي مبرمج JavaScript. تخلي الكود أنظف وأقصر، وتحل مشكلة الـ this بشكل أنيق. بس زي أي أداة، لازم تعرف متى تستخدمها صح ومتى تتجنبها. تدرب عليها وبتصير جزء أساسي من كتابتك للكود!