الدوال في جافا سكريبت JavaScript Functions

يتناول هذا المقال مفهوم الدوال في جافاسكريبيت ( JavaScript Functions) من حيث البنية والدور الوظيفي

الدوال في جافا سكريبت JavaScript Functions

للدوال (Functions) في لغة JavaScript دورًا محوريًا ، إذ تمثل الآلية الأساسية لتنظيم الكود البرمجي وتحويله إلى وحدات منطقية قابلة لإعادة الاستخدام. من خلال الدوال يمكن عزل المهام المتكررة، تقليل التكرار، وتحسين قابلية الصيانة والقراءة، وهو ما يصبح ضروريًا مع ازدياد حجم وتعقيد التطبيقات.


يتناول هذا المقال مفهوم الدالة في JavaScript من حيث البنية والدور الوظيفي، ثم يستعرض أنواع الدوال المختلفة التي توفرها اللغة وأساليب تعريفها، مع توضيح طريقة استدعاء الدوال وتمرير القيم إليها. كما يناقش المقال الدوال المتداخلة، وأهميتها في بناء منطق برمجي أكثر مرونة، خاصة في السيناريوهات التي تتطلب نطاقات (Scopes) متعددة والتحكم في تدفق التنفيذ. الهدف هو تقديم فهم واضح وعملي للدوال بوصفها عنصرًا أساسيًا لا غنى عنه في تطوير تطبيقات JavaScript.

نتعرف في هذا المقال على:



الدالة في JavaScript

الدالة في جافا سكريبت هي مجموعة من التعليمات البرمجية القابلة لإعادة الاستخدام، والتي يمكن استدعاؤها في أي مكان في البرنامج. فهي تُغني عن كتابة نفس التعليمات البرمجية مرارًا وتكرارًا، وتساعد المبرمجين على كتابة تعليمات برمجية مُجزأة. تسمح الدوال للمبرمج بتقسيم برنامج كبير إلى عدد من الدوال الصغيرة سهلة الإدارة. ومثل أي لغة برمجة متقدمة أخرى، تدعم جافا سكريبت جميع الميزات اللازمة لكتابة تعليمات برمجية مُجزأة باستخدام الدوال.

قبل استخدام أي دالة، نحتاج أولاً إلى تعريفها والطريقة الأكثر شيوعًا لتعريف دالة في جافا سكريبت هي استخدام الكلمة المفتاحية function، متبوعة باسم دالة فريد، وقائمة بالمعاملات (قد تكون فارغة)، وكتلة التعليمات البرمجية محاطة بأقواس معقوفة { }.

ولابد كتابة جميع العبارات التي تحتاج إلى تنفيذها عند استدعاء الدالة داخل الأقواس المعقوفة لتكون الصيغة العامة للتعرف دالة في JavaScript على الشكل التالي:

function functionName(parameter-list) {
    statements
}

يُطلق على هذا النوع من تعريف الدوال اسم الدوال الصريحة (Function Declarations)، ويمكن للدالة الصريحة أن ترجع قيمة بواسطة الكلمة المحجوزة return لنر المثال التالي :

function sum(a,b) {
    return a+b;
}

في ضوء ما سبق، يمكن النظر إلى الدالة في JavaScript كوحدة تنفيذ مستقلة تُعرِّف مهمة محددة وتُستدعى عند الحاجة، مما يسهّل تنظيم الكود والتحكم في منطق التطبيق. بعد التعرف على فكرة الدوال وآلية تعريفها وبنيتها الأساسية، يصبح من الضروري الانتقال إلى مستوى أعمق لفهم التنوع الذي توفره JavaScript في هذا الجانب. فإلى جانب الدوال الصريحة (Function Declarations) توفر JavaScript العديد من الأساليب المختلفة لتعريف الدوال واستخدامها، والفروق العملية بينها، ومتى يكون اختيار نوع معين أكثر ملاءمة من غيره.



أنواع الدوال في JavaScript

تعتبر الدوال (Functions) "اللبنات الأساسية" في لغة JavaScript، وهي متنوعة بشكل يسهل علينا اختيار الدالة المناسبة لكل موقف . وتوفر JavaScript أكثر من أسلوب لتعريف الدوال، ويعود هذا التنوع إلى اختلاف سياقات الاستخدام وطرق تنفيذ الكود والتحكم في النطاق وسلوك الاستدعاء.

لهذا فإن اختيار أسلوب تعريف الدالة ليس قرارًا شكليًا، بل يؤثر على قابلية القراءة، وإعادة الاستخدام، وطريقة التعامل مع السياق (`this`) وترتيب التنفيذ. نستعرض فيما يلي قائمة بأنواع الدوال الأكثر شيوعاً واستخداماً:


1. الدوال الصريحة (Function Declarations)

هي الطريقة التقليدية لتعريف الدالة حيث يتم تعريفها باستخدام الكلمة المفتاحية function متبوعة باسم الدالة.وتتميز بخاصية رفع الدوال او الـ Hoisting، بحيث يمكن استدعاء الدالة قبل سطر تعريفها في الكود. ويُعدّ رفع الدوال في جافا سكريبت سلوكًا افتراضيًا حيث تُنقل تعريفات الدوال إلى أعلى نطاقها المحلي قبل تنفيذ الكود.

بالتالي، يُمكن استدعاء الدالة في نطاقها قبل تعريفها من المهم ملاحظة أن التعريف فقط هو ما يُرفع، وليس عملية التهيئة لذا، يجب تهيئة المتغيرات أو الدوال قبل استخدامها.على سبيل المثال يمكن استخدام الدالة من المثال السابق على الشكل التالي:

sum (2,3);
function sum(a,b) {
    return a+b;
} 

وتستخدم لإنشاء دوال عامة أو أساسية داخل الملف أو الـ Module. وتكون ملائمة أكثر عندما تريد كتابة كود منظم بحيث تضع الاستدعاءات الرئيسية في البداية، وتفاصيل الدوال في الأسفل، أو عند إنشاء دوال عامة متكررة الاستخدام في أماكن مختلفة من الملف.


2. تعبيرات الدوال (Function Expressions)

هنا يتم تخزين الدالة داخل متغير حيث يستخدم هذا المتغير لاستدعاء تعبير الدالة فيتم تعريف الدالة هنا كجزء من تعبير برمجي، وعادة ما تُخزن داخل متغير (const أو let). وعلى عكس النوع الأول، لا تدعم هذه الدوال الـ Hoisting؛ لذا يجب تعريفها أولاً قبل استخدامها. كما أن الفرق الرئيسي بينهما هو اسم الدالة يمكن الإستغناء عن اسم الدالة في تعبيرات الدوال، مما يُسهِّل إنشاء دوال مجهولة في جافا سكريبت. لنرى المثال التالي :

 const sum = function(a, b) {  return a + b;};

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


3. الدوال السهمية (Arrow Functions)

صياغة حديثة ومختصرة قُدمت في إصدار ES6، حيث تتيح لنا الدوال السهمية (Arrow Functions) في جافا سكريبت إنشاء دوال مختصرة ومجهولة. تُكتب الدوال السهمية بدون الكلمة المفتاحية "function" بل يشار الى تعليمات الدالة بواسطة الرمز"<=".

الفرق الجوهري (بجانب الشكل) هو أنها لا تملك this خاصة بها، بل تأخذها من النطاق الخارجي المحيط بها.كما أنها لا تدعم الـ Hoisting (لأنها تعبيرات دوال في النهاية).. كما لا يمكن استخدامها كدوال منشئة (مع new).

أيضاً لا تحتوي على كائن المعاملات المدمج arguments. وتأخذ شكلين في الكتابة:

  const varName = (parameter-list) => Expression;
//OR
const varName = (parameter-list) => {
    // function body
}; 

لاحظ استخدام الدوال السهمية في المثال التالي:

  const multiply = (a, b) => a * b;

وتستخدم الدوال السهمية (Arrow Functions) في العمليات الحسابية السريعة، ومعالجة المصفوفات، وداخل الـ Callbacks.أوعنندما تريد كتابة كود موجز وسريع (مثل دوال المصفوفات: map, filter, reduce). كما تستخدم داخل الـ Callbacks والمؤقتات (setTimeout) للحفاظ على سياق الكائن الأب دون الحاجة لاستخدام bind(this).


4. الدوال المجهولة (Anonymous Functions)

الدوال المجهولة (Anonymous Functions) في JavaScript هي دوال تُكتب بدون اسم. لا يمكن استدعاؤها بمفردها لاحقاً لأنها لا تملك معرّفاً. لهذا لا يمكن إعادة استخدامها في مكان آخر من الكود لأنها لا تملك اسماً يربطها. ويكون تعريفها على الشكل الظاهر في المثال التالي:

 setTimeout(function() {
  console.log("The execution after one second.");
}, 1000); 

وتستخدم عادةً كـ "وسيط" (Argument) فتُمرر مباشرة لدوال أخرى (Callbacks) أو تُستخدم داخل تعبيرات الدوال.أي عندما تحتاج إلى دالة "لمرة واحدة فقط" في حدث معين (مثل النقر على زر)، ولا يوجد داعٍ لتسميتها وحجز مساحة لها في الذاكرة العامة للملف.


5- الدوال ذاتية الاستدعاء (Self-Invoking Functions)

تُعرف الدالة ذاتية الاستدعاء أيضًا بتعبير دالة مُستدعاة فورًا (IIFE) إختصاراً لعبارة Immediately Invoked Function Expression.. وهي دالة مجهولة تُغلف بأقواس () ويتم تنفيذها فوراً بمجرد قراءتها. أي هي دوال جافا سكريبت تُنفَّذ فور تعريفها. تُسمى هذه الدوال أيضًا بالدوال المجهولة ذاتية التنفيذ.

بنا أنها تعمل وتنتهي في نفس اللحظة، فهي لا تترك أي أثر أو متغيرات ملوثة في النطاق العام (Global Scope).ولها صيغتين في الكتابة..

(function () {
   // function body
})();
//OR
(function () {
   // function body
}());

لاحظ الاستخدام في المثال التالي:

 (function() {
  console.log("Hello World!");
})(); 

وتستخدم لعزل الكود وإنشاء نطاق خاص (Private Scope). بغرض حماية النطاق (Scope) ومنع تداخل المتغيرات. فتكون ملائمة عند كتابة مكتبات برمجية (Libraries) أو ملفات مستقلة للتأكد من أن متغيراتك لن تتداخل أو تصطدم مع متغيرات ملفات أخرى. أو لتشغيل كود تهيئة (Initialization) يبدأ مع بداية التطبيق ولا تحتاجه مجدداً.


جدول المقارنة السريعة لاتخاذ القرار

نوع الدالة دعم الـHoisting سياق this أفضل حالة استخدام
الصريحة (Declaration) نعم ديناميكي (يتحدد حسب من استدعى الدالة) الدوال الأساسية والعامة في المشروع.
التعبيرية (Expression) لا ديناميكي (حسب المستدعي) التقييد اللحظي للكود وتمرير الدوال كقيم.
السهمية (Arrow) لا معتمد على النطاق الخارجي الـ Callbacks ومعالجة المصفوفات والمؤقتات.
المجهولة (Anonymous) لا ديناميكي الأحداث (Event Listeners) التي تعمل لمرة واحدة.
ذاتية الاستدعاء (IIFE) لا ديناميكي حماية المتغيرات وعزل الكود عند بدء التشغيل.

من هنا يتضح لنا أن تنوع أساليب تعريف الدوال في JavaScript يهدف إلى تلبية احتياجات برمجية مختلفة، وليس مجرد تنوع لغوي. الفهم الدقيق للفروق بين الدوال الصريحة، وتعبيرات الدوال، والدوال السهمية، والدوال المجهولة، والدوال ذاتية الاستدعاء يساعد على اختيار الأسلوب الأنسب بحسب السياق، ويؤدي إلى كود أكثر وضوحًا وكفاءة. هذا الإدراك يمهّد للانتقال إلى كيفية استدعاء الدوال في JavaScript وربطها بتدفق التنفيذ داخل التطبيق.



استدعاء الدوال في جافا سكريبت

يعني استدعاء الدالة يعني "تشغيل الدالة" أو "تنفيذ الدالة"أي استدعاء الدالة في جافا سكريبت هو عملية تنفيذ دالة. فعند تعريف دالة جافا سكريبت باستخدام تعريف الدالة أو تعبير الدالة. لا يتم تنفيذ الكود الموجود داخل الأقواس المعقوفة و لتنفيذ الكود، نحتاج إلى استدعاء الدالة. حيث يكون استدعاء دالة جافا سكريبت باستخدام اسم الدالة متبوعًا بقوسين. إلا أن طرق استدعاء الدوال في جافا سكريبت متعددة بناءً على كيفية تعريف الدالة والسياق الذي تُستخدم فيه. فيما يلي أبرز هذه الطرق:

1. الاستدعاء المباشر (Direct Call)

الطريقة الأكثر شيوعاً، حيث يتم كتابة اسم الدالة متبوعاً بأقواس (). لاحظ المثال التالي:

 function sayHello() {
  console.log("Hello!");
}

sayHello(); // Direct Call

2. الاستدعاء كأسلوب (Method) في كائن(Object)

تعرف هذه الطريقة بـ (Method Invocation) وتستخدم عندما تكون الدالة جزءاً من كائن (Object)، ( دالة داخل كائن) فيتم استدعاؤها باستخدام نقطة الربط (.) حيث يكتب اسم الكائن ثم نقطة ثم اسم الدالة تمامًاً كما هو موضح في المثال التالي:

 // Declare an object with the name “user”
const user = {
  name: "Noor",
  greet: function() {
    console.log("Hello " + this.name);
  }
};

user.greet(); // call function form object 

3. الاستدعاء باستخدام call و apply

في جافا سكريبت، كل دالة هي كائن (Object) من نوع Function ويوفر Function خصائص طُرق (Methods) استخدام (Methods) للدوال. تُعرَّف هذه الخصائص والطُرق في Function.prototype وتُشارك بين جميع نسخ Function. من أهم هذه الأساليب التي يوفرها كائن Function هي call() و apply() و bind(). تُستخدم هذه الطرق لتحديد قيمة this يدوياً عند استدعاء الدالة. ولكل منها استخدام معين فمثلاً call و apply تستخدم لغرض الاستدعاء… مع فرق في طريقة الاستدعاء فقط فتعمل كتالي:

  • call: تمرر الوسائط (arguments ) بشكل منفصل.
  • apply: تمرر الوسائط (arguments) كصفوفة (Array).

ويوضح المثال التالي الفرق في طريقة الاستدعاء بينهما:

function intro(city, country) {
  console.log(`I’m from ${city} in ${country}`); }

intro.call(null, "Riyadh", "Saudi Arabia "); // calling by call()
intro.apply(null, ["Tabuk", "Saudi Arabia"]);// calling by apply() 

4. الاستدعاء كدالة بنائية (Constructor Call)

تُستخدم عند إنشاء كائن جديد من "صنف Calss" أو دالة باستخدام الكلمة المحجوزة new. لاحظ /ي المثال التالي:

 function Person(name) {
  this.name = name; }
const person1 = new Person("Sara"); 

5. الاستدعاء عبر أحداث DOM (Event Driven)

يتم تنفيذ الدالة عند وقوع حدث معين من قبل المستخدم (مثل النقر على زر). كما يظهر المثال التالي:

 <!--In the HTML Document -->
<button onclick="alertMe()">Click Here</button>
<!--JavaScript code-->
<script>
    function alertMe() {
      alert("Welcome!");
    }
</script> 

6. الدوال التي تستدعي نفسها

كما عرفنا الدوال ذاتية الاستدعاء (Self-Invoking Functions) انها تُعرف بـ Immediately Invoked Function Expressions، وهي دوال تُنفذ بمجرد تعريفها مباشرة.


(function() {
console.log("Helloاً!");
})(); 

7.استدعاء الدوال السهمية (Arrow Functions)

تُستدعى بنفس الطريقة المباشرة، لكنها تختلف في كيفية تعاملها مع كلمة this (حيث لا تملك this خاصاً بها بل تأخذه من النطاق المحيط).

 const add = (a, b) => a + b;console.log(add(5, 10));

نصيحة برمجية:

اختيار طريقة الاستدعاء يعتمد على حاجتك؛ فإذا كنت تعمل على معالجة البيانات داخل المصفوفات، قد تفضل استخدام apply أو spread operator مع الاستدعاء المباشر، بينما في البرمجة الكائنية ستعتمد أكثر على Methods و Constructors.

—----------------------------

ملاحظة : وردت منعا الاشارة الى كلمة this هي كلمة محجوزة في JavaScript ومن أكثر الكلمات المحجوزة أهمية وإثارة للجدل في نفس الوقت. ببساطة، هي "كلمة مرجعية" تشير إلى الكائن (Object) الذي ينتمي إليه الكود الحالي أثناء التنفيذ. بمعنى أن قيمة this ليست ثابتة، بل تعتمد على كيفية استدعاء الدالة وليس أين كُتبت (باستثناء الدوال السهمية). فيما يلي الحالات الأربع الرئيسية :

  • داخل كائن (Object Method): فعندما تكون الدالة جزءاً من كائن (object)، فإن this تشير إلى الكائن نفسه.
  • بمفردها أو في دالة عادية (Global Context) : إذا استخدمت this خارج أي كائن أو داخل دالة بسيطة، فإنها تشير إلى الكائن العالمي (Global Object) مثلاً في المتصفح تشير إلى window وفي وضع "الوضع الصارم" (use strict) تكون قيمتها undefined.
  • مع الدوال السهمية (Arrow Functions): الدوال السهمية لا تملك this خاصة بها هي تبحث عن قيمة this في المكان الذي "وُلدت" فيه (النطاق الخارجي).
  • مع المشيد (Constructor / Classes):عند استخدام الكلمة المفتاحية new لإنشاء كائن جديد، فإن this تشير إلى الكائن الجديد الذي يتم إنشاؤه حالياً.

—----------------------------

لا يكتمل فهم الدوال في JavaScript دون إدراك الكيفية التي يتم بها استدعاؤها وتنفيذها، إذ تختلف نتيجة التنفيذ وسلوك الدالة باختلاف أسلوب الاستدعاء المستخدم. طريقة الاستدعاء لا تحدد فقط متى تعمل الدالة، بل تؤثر أيضًا على قيمة السياق (`this`) وآلية تمرير المعطيات ودور الدالة داخل التطبيق.هذا الإدراك يمهّد للحديث عن الدوال المتداخلة في JavaScript وفهم كيفية تفاعل الدوال مع بعضها داخل نطاقات تنفيذ متعددة.



الدوال المتداخلة في JavaScript - استخدام الـ Callback للإستدعاء

تُعد الدوال المتداخلة في JavaScript مدخلًا أساسيًا لفهم كيفية تمرير الدوال كقيم واستخدامها ضمن منطق تنفيذ أكثر مرونة. في هذا السياق يظهر مفهوم Callback بوصفه آلية تعتمد على تمرير دالة إلى دالة أخرى ليتم استدعاؤها لاحقًا وفق شرط أو تسلسل محدد.

الـCallback للاستدعاء يعني استخدام الدالة كا عامل (parameter) في دالة اخرى يمكن ان تكون الدالة المستخدمة كا براميتر معرفة مسبقاً ويمكن أن تعرف في مكان البراميتر وفي هذه الحالة تستخدم مرة واحدة فقط.. هنا بعض الأمثلة توضح طريقة الاستخدام..

يوضح المثال استخدام الـ Callback عبر طريقة استخدام شائع، فنرى استدعاء الدوال sum و sub في استدعاء الدالة log ..

function sum (a, b) {
    return `[${a + b}]`;
}
function sub (a, b) {
    return `[${a - b}]`;
}

console.log(sum(2,3)); //[5]
console.log(sub(3,4)); //[-1] 

إن استدعاء الدوال بشكل مباشر كما في المثال السابق قد يكون غير عملي مع وظائف أكثر لهذا يمكن استخدام دالة واحدة نستدعي بواسطتها الوظيفة المطلوبة كما في المثال التالي:

function operation (a, b, funcallBack)
{
    return `[${funcallBack(a , b)}]`; // return the result as string 

}
 console.log(operation(3,4 ,sum)) ; // sum is callback function //[7]
 console.log(operation(3,4 ,sub)) ; //[-1] 

ذكرنا في مقدمة الحديث عن الـ Callback وجود طريقتين له أما ان تكون الدالة معرفة مسبقاَ كما أوضحت الأمثلة السابقة أو أن يتم تعريف الدالة في مكان الاستدعاء، كم يوضح المثال التالي:

 function operation (a, b, funcallBack){
	return `[${funcallBack(a , b)}]`; }

console.log(operation(5,3 ,function(a, b){
 	return a +b;})) ;  

يعمل الـ callback بفعالية مع الدوال السهمية (Arrow Function) كما يوضح المثال التالي :


//callback with Arrow function  (paramters) => { return function code} or (paramters) => function code
console.log(operation(5,1 ,(a, b)=> a + b)) ; // [6]
//One line code is the default return 

//callback with Arrow function which defined before 
const sum = (a, b)=> a + b;
console.log(operation(5,2 ,sum)); //[7]
console.log(operation(10,4 ,sum)); // [14]

يتضح أن الدوال المتداخلة ومفهوم الـ Callback يمثلان حجر أساس في أسلوب البرمجة في JavaScript، خاصة عند التعامل مع التدفق غير المتزامن وتنفيذ المهام بالترتيب المطلوب. استخدام الدوال داخل دوال أخرى، وتمريرها كوسائط، أو تعريفها بصيغة دوال سهمية، يوفّر درجة عالية من المرونة والتحكم في منطق التنفيذ. الفهم الواعي لهذه الآلية يساعد على قراءة الكود بشكل أدق وكتابته بطريقة أكثر تنظيمًا، ويمهّد للتعامل مع مفاهيم متقدمة مثل البرمجة غير المتزامنة وإدارة الأحداث في التطبيقات الحديثة.



في ختام هذا المقال، يتضح أن الدوال في JavaScript ليست مجرد أداة لتنفيذ أوامر، بل هي أساس لبناء شيفرة منظمة وقابلة للتوسع. فهم مفهوم الدالة، والتمييز بين أنواعها المختلفة، وإتقان طريقة استدعائها واستخدامها داخل دوال أخرى، ينعكس مباشرة على جودة التصميم البرمجي وكفاءة التنفيذ. كلما كان التعامل مع الدوال أكثر وعيًا من حيث النطاق، وإعادة الاستخدام، وتوزيع المسؤوليات، أصبح من الأسهل تطوير تطبيقات أكثر استقرارًا ووضوحًا، سواء في المشاريع الصغيرة أو الأنظمة البرمجية المعقدة.

إرسال تعليق

فضلاً اترك تعليق
موافقة ملفات تعريف الارتباط
لتحسين تجربتك… يستخدم موقعنا ملفات تعريف الارتباط (Cookies)
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.