تخطَّ إلى المحتوى

الدوال السهمية والنطاق في JavaScript

الدرس 12 من 28 · JavaScript

في الدرس السابق كتبنا الدوال بكلمة function. في JavaScript الحديثة ستجد طريقة أقصر بكثير يستخدمها المبرمجون في كل مكان: الدوال السهمية (Arrow Functions). وفي النصف الثاني من الدرس ستفهم النطاق (Scope)، أي القاعدة التي تحدد أين «يعيش» كل متغير وأين يمكنك استخدامه.

قارن بين الطريقتين لكتابة نفس الدالة:

// الطريقة التقليدية
function square(n) {
return n * n;
}
// الدالة السهمية
const square = (n) => n * n;

الدالة السهمية تُحفظ في متغير (غالباً بـ const)، ثم تأتي المعاملات بين قوسين، ثم السهم =>، ثم النتيجة. اقرأها هكذا: «الدالة square تأخذ n وتعطي n × n».

const square = (n) => n * n;
console.log(square(5));
const add = (a, b) => a + b;
console.log(add(3, 4));
الناتج
25
7

لاحظ أننا لم نكتب return ولا الأقواس المعقوفة. عندما يكون جسم الدالة تعبيراً واحداً، تُرجع الدالة السهمية قيمته تلقائياً. هذا يسمى «الإرجاع الضمني».

// بدون معاملات: قوسان فارغان
const sayHi = () => console.log("مرحباً!");
sayHi();
// معامل واحد: يمكن حذف القوسين
const doubleIt = n => n * 2;
console.log(doubleIt(21));
// عدة أسطر: أقواس معقوفة و return صريحة
const describe = (name, age) => {
const status = age >= 18 ? "بالغ" : "قاصر";
return `${name} ${status}`;
};
console.log(describe("علي", 20));
الناتج
مرحباً!
42
علي بالغ

ستحب الدوال السهمية كثيراً في الدرس القادم، عندما نمررها لدوال المصفوفات مثل map و filter.

النطاق هو المكان الذي يمكن فيه رؤية المتغير واستخدامه. تخيّل بيتاً فيه غرف. الأشياء الموجودة في الصالة يراها كل من في البيت. أما الأشياء الموجودة داخل غرفتك فلا يراها إلا من يدخل غرفتك.

const siteName = "مدرسة البرمجة"; // عام: في الصالة
function showSite() {
const page = "الرئيسية"; // محلي: داخل غرفة الدالة
console.log(siteName, "-", page);
}
showSite();
console.log(page);
الناتج
مدرسة البرمجة - الرئيسية
ReferenceError: page is not defined
  • المتغير siteName معرّف خارج أي دالة، فهو عام (Global) ويمكن استخدامه في أي مكان، حتى داخل الدالة.
  • المتغير page معرّف داخل الدالة، فهو محلي (Local) ويختفي بمجرد انتهاء الدالة. محاولة استخدامه من الخارج تسبب خطأ.

المتغيرات التي تنشئها بـ let و const تعيش داخل أقرب قوسين معقوفين { } فقط، سواء كانت لدالة أو لـ if أو لحلقة:

if (true) {
let secret = 42;
console.log(secret);
}
console.log(secret);
الناتج
42
ReferenceError: secret is not defined

هذا سبب آخر لتفضيل let و const على var، فـ var لا تحترم حدود الكتلة.

يمكن أن يوجد متغيران بنفس الاسم في نطاقين مختلفين، والأقرب هو الذي يُستخدم:

let color = "أزرق";
function paint() {
let color = "أحمر";
console.log("داخل الدالة:", color);
}
paint();
console.log("خارج الدالة:", color);
الناتج
داخل الدالة: أحمر
خارج الدالة: أزرق

المتغير الداخلي «يغطي» الخارجي داخل الدالة فقط، ولا يغيّره.

الدالة تستطيع تعديل متغير خارجي

Section titled “الدالة تستطيع تعديل متغير خارجي”

الدالة ترى المتغيرات الموجودة في النطاق الأوسع، وتستطيع تعديلها أيضاً:

let score = 0;
const addPoint = () => {
score++;
};
addPoint();
addPoint();
console.log(score);
الناتج
2

حوّل الدوال الثلاث إلى أشكال مختلفة، وجرّب أن تطبع bonus خارج الدالة لترى خطأ النطاق:

جرّب بنفسكJavaScript
أو اضغط Ctrl + Enter

الناتج

  • نسيان return مع الأقواس المعقوفة: const add = (a, b) => { a + b }; تُرجع undefined.
  • استخدام متغير محلي خارج دالته: يسبب ReferenceError. عرّف المتغير في النطاق الذي تحتاجه فيه.
  • استدعاء الدالة السهمية قبل تعريفها: الدالة المخزنة في const لا يمكن استدعاؤها في سطر يسبق تعريفها.

سؤال

ما ناتج const triple = (n) => n * 3; console.log(triple(4));؟

سؤال

متغير عرّفته بـ let داخل جملة if، أين يمكنك استخدامه؟

  • الدالة السهمية تُكتب (معاملات) => نتيجة، وتُرجع التعبير الواحد تلقائياً.
  • مع الأقواس المعقوفة { } يجب كتابة return صراحة.
  • النطاق يحدد أين يُرى المتغير: عام في كل مكان، ومحلي داخل دالته فقط.
  • let و const تعيشان داخل أقرب كتلة { }.
  • اجعل كل متغير في أضيق نطاق يحتاجه.