تعبيرات الدوال

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

const myVariable = function() { };

يمكنك بعد ذلك استدعاء تعبيرات الدوال باستخدام معرّف المتغيّر:

const myVariable = function() {
    console.log( "This is my function." );
};

myVariable();
> "This is my function."

يمكنك أيضًا استخدام تعبيرات الدوال لإنشاء دوال مُسمّاة باستخدام بناء جملة يشبه تعريفات الدوال:

const myVariable = function myFunction() {
    console.log( "This is my function." );
};

myVariable();
> "This is my function."

ومع ذلك، على عكس إعلانات الدالة، يمكن الوصول إلى تعبير الدالة المُسمّاة من خلال اسم الدالة فقط داخل الدالة نفسها:

const myVariable = function myFunction() {
  console.log( `I'm a ${ typeof myFunction }.`);
};

typeof myFunction;
> "undefined"

typeof myVariable;
> "function"

myVariable();
> "I'm a function."

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

const myVariable = function myFunction() {
    console.log( "One second elapsed." );
    setTimeout( myFunction, 1000 );
};

setTimeout( myVariable, 1000 );
> "One second elapsed."
> "One second elapsed."
> "One second elapsed."
…

تعبيرات دوال الأسهم

تم تقديم تعبيرات دوال السهم (غالبًا ما تُسمّى "دوال الأسهم" أو نادرًا ما تستخدم "دوال lambda") في ES6 لتوفير بناء جملة موجز لإنشاء تعابير دوال مجهولة مع بعض السلوكيات الفريدة.

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

const myFunction = () => {};

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

const myFunction = myParameter => {};

عندما تريد أن يعرض نص الدالة قيمة تعبير مفرد، لا يلزم تضمين نص الدالة بين أقواس معقوفة ولا الكلمة الرئيسية return:

const myFunction = () => 2 + 2

myFunction()
> 4

وتتميز دوال الأسهم بأنها فريدة من نوعها لأنها لا تتضمن سياقًا خاصًا لقيم arguments أو this. بدلاً من ذلك، تكتسب القيمتان من بيئة التضمين اللغوي الخاصة بدالة السهم، وهي أقرب دالة تضمين توفر هذه السياقات.

function myParentFunction() {
    this.myProperty = true;
    let myFunction = () => {
            console.log( this );
    }
    myFunction();
};

let myInstance = new myParentFunction();
> Object { myProperty: true }

دوال أسهم الاستدعاء

لا تربط الدوال الأسهم الوسيطات بالطريقة نفسها التي تربط بها أنواع الدوال الأخرى. يكتسب كائن arguments في نص الدالة السهمية قيمته من أقرب بيئة تضمين معجمية تابعة لدالة السهم هذه:

function myFunction() {
    let myArrowFunction = () => {
            console.log( arguments[ 0 ] );
    }
    myArrowFunction( true );
};

myFunction( false );
> false

في هذا المثال، تستدعي دالة خارجية تُسمى الوسيطة false دالة سهم داخلي باستخدام الوسيطة true. بما أنّ الكائن arguments داخل دالة السهم يتحوّل إلى الارتباط في الدالة الخارجية، تسجّل الدالة الداخلية الدالة false للدالة الخارجية.

إذا لم يكن هناك كائن arguments يمكن اكتسابه من السياق الأصلي، لن يتم تحديد كائن arguments الخاص بدالة السهم، وتتسبب محاولة الوصول إليه في حدوث خطأ:

let myArrowFunction = () => {
    console.log(arguments);
};
myArrowFunction( true );
> Uncaught ReferenceError: arguments is not defined

تعبيرات الدوال التي يتم استدعاءها فورًا (IIFE)

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

(function() {
    console.log( "IIFE.")
    }
)();
> "IIFE."

(function() {
    console.log( "IIFE.")
    }
());
> "IIFE."

يستدعي المثال الأول تعبير الدالة المجمّع. يستدعي المثال الثاني إعلان دالة داخل عوامل التجميع، ثم يتم تقييم النتيجة النهائية كتعبير مجمّع. والنتيجة هي نفسها في كلتا الحالتين.

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

( () => {
    console.log( "IIFE." );
}() );
> Uncaught SyntaxError: missing ) in parenthetical

نظرًا لأن مشغلات التجميع تتوقع تعبيرًا، يتم تعريف دالة السهم بداخلها، مما يسمح للأقواس التي تتبعها باستدعاء التعبير المجمّع:

( () => {
    console.log( "IIFE." );
} )();
> "IIFE."

التطبيقات القديمة، التي يتم استخدامها بشكل متكرّر في IIFE لإدارة النطاق، وتحديدًا لتجنُّب تلويث النطاق العالمي باستخدام المتغيّرات على مستوى الوظيفة وبيانات الوظائف قبل طرح تحديد نطاق الحظر في ES6، كان من الشائع أن يتم إدراج نص برمجي كامل في IIFE لمنع التلوث غير المقصود للنطاق العالمي.

التحقق من فهمك

هل يمكنك استدعاء تعبير دالة مُسمّى حسب الاسم خارج الدالة؟

لا
نعم