انتقل إلى المحتوى

٢.١ الدوال

ما الدالة؟

التمرين 1: عاد صديقنا علي! يريد أن نرحّب به كلما طلب ذلك.

console.log("Hello Ali");

صحيح، لكننا لم نعالج الجزء الذي يقول: كلما طلب ذلك.

التمرين 2: اقرأ الشيفرة وتحقّق من النتيجة.

function greetAli(){
  console.log("Hello Ali");
}

greetAli(); // Ali wants us to greet him
greetAli(); // Ali wants us to greet him
greetAli(); // Ali wants us to greet him
greetAli(); // Ali wants us to greet him

النتيجة كما يلي:

Hello Ali
Hello Ali
Hello Ali
Hello Ali

لنفكّر في المطلوب مجددًا:

  1. يريد علي أن نرحّب به عند الطلب. فإذا قال: رحّبوا بي الآن، فعلينا فعل ذلك فورًا.
  2. يمكن وضع رسالة الترحيب في كتلة شيفرة لها اسم. وعند الحاجة نستدعي هذه الكتلة باسمها.
  3. لإنشاء هذه الكتلة في JavaScript، نستخدم الكلمة المفتاحية function، ونُسمّي الدالة "greetAli".
  4. كلما أراد علي ترحيبًا، نستدعي الدالة باسمها، فتظهر الرسالة في وحدة التحكم.

التمرين 3: اقرأ الشيفرة وتحقّق من النتيجة.

function greetOla(){
  console.log("Hello Ola");
}

greetOla(); // Ola wants us to greet her
greetOla(); // Ola wants us to greet her
greetOla(); // Ola wants us to greet her
greetOla(); // Ola wants us to greet her
greetOla(); // Ola wants us to greet her
greetOla(); // Ola wants us to greet her

النتيجة كما يلي:

Hello Ola
Hello Ola
Hello Ola
Hello Ola
Hello Ola
Hello Ola

استخدمنا أسلوب function للترحيب بعلا أيضًا.

كيف نُنشئ دالة؟

  1. استخدم الكلمة المفتاحية function لتعريف دالة جديدة.
  2. أعطِ الدالة اسمًا تختاره، مثل greetOla.
  3. اكتب قوسي الاستدعاء ().
  4. اكتب قوسًا معقوفًا مفتوحًا {.
  5. اكتب التعليمات التي تريد تنفيذها عند استدعاء الدالة، مثل console.log("Hello");
  6. اكتب قوسًا معقوفًا مغلقًا }.

كيف نستدعي دالة؟

  1. اكتب اسم الدالة، مثل greetOla.
  2. اكتب قوسين دائريين ().

التمرين 4: عُدّ من 1 إلى 10 كلما طلب منك سند ذلك.

function countTo10(){
  for(var i=1; i<=10; i++){
    console.log(i);
  }
}

// Sanad ask you to count now
countTo10()

النتيجة كما يلي:

1
2
3
4
5
6
7
8
9
10

التمرين 5: اعرض الجمل التالية في وحدة التحكم:

  1. "Hello there"
  2. "Welcome to our website!"
  3. "We are glad to have you with us."
  4. "Here is the content of our website."
  5. "Hello there"
  6. "Welcome to our website!"
  7. "We are glad to have you with us."
console.log("Hello there");
console.log("Welcome to our website!");
console.log("We are glad to have you with us.");
console.log("Here is the content of our website.");
console.log("Hello there");
console.log("Welcome to our website!");
console.log("We are glad to have you with us.");

النتيجة كما يلي:

Hello there
Welcome to our website!
We are glad to have you with us.
Here is the content of our website.
Hello there
Welcome to our website!
We are glad to have you with us.

هناك تكرار كثير في شيفرة التمرين 5 . بعد أن تعلّمنا الدوال، يمكننا استخدامها لتجنّب التكرار.

لا تكرّر نفسك!

مبدأ «لا تكرّر نفسك» (DRY) يعني تجنّب كتابة الشيفرة نفسها مرارًا. ابحث عن طريقة لإعادة استخدامها، مثل الحلقات والدوال.

التمرين 6: أعد تنفيذ التمرين 5مع تطبيق مبدأ DRY.

function greeting(){
  console.log("Hello there");
  console.log("Welcome to our website!");
  console.log("We are glad to have you with us.");
}

greeting();
console.log("Here is the content of our website.");
greeting();

سترى النتيجة نفسها:

Hello there
Welcome to our website!
We are glad to have you with us.
Here is the content of our website.
Hello there
Welcome to our website!
We are glad to have you with us.

لماذا نستخدم الدوال؟

نستخدم الدوال لإعادة استخدام كتلة شيفرة مرات متعددة.

التمرين 7: لا يستطيع الإعجاب بالمنشورات أو إضافة التعليقات إلا المستخدم المسجّل دخوله. يريد مستخدم الإعجاب بمنشور وإضافة تعليق.

١- اعرض "Let's see if you are logged in" في وحدة التحكم.

٢- تحقّق مما إذا سجّل المستخدم دخوله.

٣- اعرض "The user wants to like a post"، وتحقّق من تسجيل الدخول.

٤- اعرض "The user wants to add a comment"، وتحقّق من تسجيل الدخول.

افترض أن المستخدم مسجّل دخوله. تلميح: اتبع مبدأ DRY .

var userLoggedIn = true;

function isLoggedIn(){
  if(userLoggedIn){
    console.log("He is logged in.")
  }else{
    console.log("He is not logged in.");
  }
}

console.log("Let's see if you are logged in");
isLoggedIn();
console.log("The user wants to like a post");
isLoggedIn();
console.log("The user wants to add a comment");
isLoggedIn();

النتيجة كما يلي:

Let's see if you are logged in
He is logged in.
The user wants to like a post
He is logged in.
The user wants to add a comment
He is logged in.

التمرين 8: أعد تنفيذ التمرين 7. افترض أن المستخدم غير مسجّل دخوله.

var userLoggedIn = false;

function isLoggedIn(){
  if(userLoggedIn){
    console.log("He is logged in.")
  }else{
    console.log("He is not logged in.");
  }
}

console.log("Let's see if you are logged in");
isLoggedIn();
console.log("The user wants to like a post");
isLoggedIn();
console.log("The user wants to add a comment");
isLoggedIn();

النتيجة كما يلي:

Let's see if you are logged in
He is not logged in.
The user wants to like a post
He is not logged in.
The user wants to add a comment
He is not logged in.

عبارة return

التمرين 9: اقرأ الشيفرة التالية وحاول فهمها.

var userLoggedIn = false;

function isLoggedIn(){
  if(userLoggedIn){
    return "He is logged in.";
  }else{
    return "He is not logged in.";
  }
}

var isLoggedInReturned = isLoggedIn();
console.log(isLoggedInReturned);

النتيجة هي: He is not logged in.

لنفهم هذه الشيفرة:

  1. صرّحنا عن متغير باسم userLoggedInوأسندنا إليه false.
  2. أنشأنا دالة باسم isLoggedIn.
  3. isLoggedIn تتحقّق الدالة مما إذا كان userLoggedIn صحيحًا أم خطأ.
  4. إذا كان userLoggedIn صحيحًا، تُرجع الدالة "He is logged in".
  5. إذا كان userLoggedIn خطأ، تُرجع الدالة "He is not logged in".
  6. ثم أنشأنا متغيرًا جديدًا باسم isLoggedInReturned.
  7. أسندنا القيمة المُرجعة من الدالة isLoggedIn إلى isLoggedInReturned.
  8. عرضنا قيمة isLoggedInReturned في وحدة التحكم.

ما المقصود بـ return?

؟ بدلًا من عرض النتيجة داخل الدالة، يمكننا تحديد قيمة تُرجعها باستخدام return .

القيمة المُرجعة هي ناتج استدعاء الدالة، ويمكن استخدامه خارجها.

التمرين 10: اقرأ الشيفرة وحاول فهمها.

var userLoggedIn = false;

function isLoggedIn(){
  if(userLoggedIn){
    return "He is logged in.";
  }else{
    return "He is not logged in.";
  }
}

isLoggedIn();

لا يظهر شيء في وحدة التحكم؛ فالدالة تُرجع قيمة لكنها لا تطبعها. لعرضها يمكنك حفظها في متغير ثم طباعته، كما فعلنا في التمرين 9.

التمرين 11: أنشئ دالة تضيف 2 إلى عدد مُعطى وتُرجع النتيجة، ثم اعرضها في وحدة التحكم.

var num = 2;
function add2(){
  return 2 + num;
}

var numPlus2 = add2();
console.log(numPlus2);

النتيجة هي: 4.

التمرين 12: أنشئ دالة تُرجع "You are not allowed here."، واعرض النتيجة في وحدة التحكم.

function accessDenied(){
  return "You are not allowed here.";
}

console.log(accessDenied());

النتيجة هي: You are not allowed here.

التمرين 13: أنشئ دالة تُرجع "You can access this page."، واعرض النتيجة في وحدة التحكم.

function accessGranted(){
  return "You can access this page.";
}

console.log(accessGranted());

النتيجة هي: You can access this page.

التمرين 14: أنشئ دالة تتحقّق من حظر المستخدم. إذا كان محظورًا فأرجع "You are not allowed here"؛ وإلا فأرجع "You can access this page.".

var userBlocked = true;

function isBlocked(){
  if(userBlocked){
    return "You are not allowed here."
  }else{
    return "You can access this page.";
  }
}

console.log(isBlocked());

النتيجة هي: You are not allowed here.

التمرين 15: أنشئ دالة تضيف 2 إلى كل عدد من 1 إلى 10 وتُرجع الناتج. استدعِها واعرض النتيجة.

function add2(){
  for(var i=1; i<= 10; i++){
    return 2 + i;
  }
}
console.log(add2());

النتيجة هي: 3.

توقّعنا إضافة 2 إلى كل عدد، لكن ذلك لم يحدث؛ لأن الوصول إلى عبارة return يُنهي تنفيذ الدالة ويُرجع القيمة المحدّدة في return . سنعيد هذا التمرين لاحقًا.

التمرين 16: أنشئ دالة تُرجع true.

function returnsTrue(){
  return true;
}

console.log(returnsTrue());

النتيجة هي: true.

التمرين 17: أنشئ دالة تُرجع 100.

function returns100(){
  return 100;
}

console.log(returns100());

النتيجة هي: 100.

التمرين 18: أنشئ دالة تُرجع null.

function returnsNull(){
  return null;
}

console.log(returnsNull());

النتيجة هي: null.

التمرين 19: أنشئ دالة فارغة لا تحتوي على تعليمات.

function returnsNothing(){
  // Nothing here
}

console.log(returnsNothing());

النتيجة هي: undefined.

ملاحظة

إذا استدعيت دالة لا تحتوي على عبارة return ، فستكون القيمة المُرجعة undefined.

undefined. لماذا؟ undefined إذا انتهى تنفيذ الدالة دون إرجاع قيمة صريحة، فإن القيمة المُرجعة افتراضيًا هي undefined.

التمرين 20: افحص القيمة المُرجعة من التمرين 2 ؟

function greetAli(){
  console.log("Hello Ali");
}

var returnValue = greetAli();
console.log(returnValue);

النتيجة كما يلي:

Hello Ali
undefined

التمرين 21: افحص القيمة المُرجعة من التمرين 4 ؟

function countTo10(){
  for(var i=1; i<=10; i++){
    console.log(i);
  }
}

var returnValue = countTo10();
console.log(returnValue);

النتيجة كما يلي:

1
2
3
4
5
6
7
8
9
10
undefined

عبارة return

عند تنفيذ عبارة return تنتهي الدالة وتُرجع القيمة المحدّدة.

يمكن أن تُرجع الدالة سلسلة نصية أو عددًا أو قيمة منطقية أو null أو أي قيمة أخرى.

إذا لم تُحدّد قيمة مُرجعة، فستكون undefined.

المعاملات والوسائط

التمرين 22: أعدنا كتابة شيفرة التمرين 2. اقرأ التالي وحاول فهمه.

function greetSomeone(name){
  console.log("Hello " + name);
}

greetSomeone("Ali"); // Ali wants us to greet him
greetSomeone("Ali"); // Ali wants us to greet him
greetSomeone("Ali"); // Ali wants us to greet him
greetSomeone("Ali"); // Ali wants us to greet him

النتيجة كما يلي:

Hello Ali
Hello Ali
Hello Ali
Hello Ali

وسّعنا شيفرة التمرين 2 . يمكنك الترحيب بشخص جديد بتغيير القيمة التي تُمرّرها عند استدعاء الدالة.

التمرين 23: يمكننا استخدام الدالة المنشأة في التمرين 22 مرة أخرى في التمرين 3.

function greetSomeone(name){
  console.log("Hello " + name);
}

greetSomeone("Ola"); // Ola wants us to greet her
greetSomeone("Ola"); // Ola wants us to greet her
greetSomeone("Ola"); // Ola wants us to greet her
greetSomeone("Ola"); // Ola wants us to greet her
greetSomeone("Ola"); // Ola wants us to greet her
greetSomeone("Ola"); // Ola wants us to greet her

النتيجة كما يلي:

Hello Ola
Hello Ola
Hello Ola
Hello Ola
Hello Ola
Hello Ola

التمرين 24: استخدم الدالة التمرين 22 للترحيب بسند مرتين.

function greetSomeone(name){
  console.log("Hello " + name);
}

greetSomeone("Sanad");
greetSomeone("Sanad");

النتيجة كما يلي:

Hello Sanad
Hello Sanad

التمرين 25: أضف 2 إلى العدد الذي يُقدّمه المستخدم، واعرض النتيجة. تلميح: استخدم الدوال.

function add2(userNumber){
  return userNumber + 2;
}
console.log(add2(5));
console.log(add2(10));

النتيجة كما يلي:

7
12

التمرين 26: أعد تنفيذ التمرين 15، واعرض ناتج إضافة 2 إلى كل عدد من 1 إلى 10. تلميح: استخدم التمرين 25 ؟

for(var i=1; i<=10; i++){
  console.log(add2(i));
}

النتيجة كما يلي:

3
4
5
6
7
8
9
10
11
12

التمرين 27: أعدنا كتابة شيفرة التمرين 8. اقرأها وحاول فهمها.

function isLoggedIn(userLoggedIn){
  if(userLoggedIn){
    console.log("He is logged in.")
  }else{
    console.log("He is not logged in.");
  }
}

console.log("Let's see if you are logged in");
isLoggedIn(false);
console.log("The user wants to like a post");
isLoggedIn(false);
console.log("The user wants to add a comment");
isLoggedIn(false);

النتيجة كما يلي:

Let's see if you are logged in
He is not logged in.
The user wants to like a post
He is not logged in.
The user wants to add a comment
He is not logged in.

المعاملات والوسائط

الاسم الذي نضعه في تعريف الدالة لاستقبال قيمة يُسمّى معاملًا (Parameter). في التمرين 22, name هو معامل.

القيمة التي نُمرّرها عند استدعاء الدالة تُسمّى وسيطًا (Argument). في التمرين 22، تكون "Ali" وسيطًا.

التمرين 28: أنشئ دالة تجمع عددين.

function addNumbers(num1, num2){
  return num1 + num2;
}

console.log(addNumbers(2,10));
console.log(addNumbers(8,40));
console.log(addNumbers(50,222));

النتيجة كما يلي:

12
48
272

الدوال تسهّل العمل؛ حدّد المعاملات التي تحتاجها لمعالجة القيم داخل الدالة. مثلًا في التمرين 28تحتاج الدالة إلى عددين: num1 و num2. وعند الاستدعاء، نحدّد القيم، أيالوسائط، التي نريد معالجتها. لجمع 10 و2 كتبنا addNumbers(2,10)

التمرين 29: أنشئ دالة تجمع أربعة أعداد.

function addNumbers(num1, num2, num3, num4){
  return (num1 + num2 + num3 + num4);
}

console.log(addNumbers(1,2,3,4));
console.log(addNumbers(55,8,5,3));
console.log(addNumbers(546,254,20,8));

النتيجة كما يلي:

10
71
828

التمرين 30: أنشئ دالة تتحقّق مما إذا كانت القيمة سلسلة نصية فارغة.

function isEmpty(value){
  return (value === "");
}

console.log(isEmpty(""));
console.log(isEmpty(null));
console.log(isEmpty(undefined));
console.log(isEmpty("Hello"));

النتيجة كما يلي:

true
false
false
false

التمرين 31: أنشئ دالة تتحقّق مما إذا كانت القيمة null أو undefined أو "" أو false.

function isFalse(value){
  return (!value);
}

console.log(isFalse(""));
console.log(isFalse(null));
console.log(isFalse(undefined));
console.log(isFalse("Hello"));

النتيجة كما يلي:

true
true
true
false

في التمرين 31نريد إرجاع true إذا كانت القيمة كاذبة، وإرجاع false إذا كانت صادقة؛ لذلك كتبنا !value.

التمرين 32: أنشئ دالة تُرجع القيمة نفسها إذا كانت صادقة، وإلا فتُرجع false.

function validateValue(value){
  if(!value){
    return false;
  }else{
    return value;
  }
}

console.log(validateValue(""));
console.log(validateValue(null));
console.log(validateValue(undefined));
console.log(validateValue("Hello"));

النتيجة كما يلي:

false
false
false
Hello

التمرين 33: أعدنا كتابة التمرين 32 . اقرأ الشيفرة وحاول فهمها.

function validateValue(value){
  return value || !!value;
}

console.log(validateValue(""));
console.log(validateValue(null));
console.log(validateValue(undefined));
console.log(validateValue("Hello"));

ستكون النتيجة:

false
false
false
Hello

لنعد إلى الأساسيات! || هو العامل المنطقي OR ، الذي يكتفي بتحقق أحد الشروط؛ ومع القيم المنطقية تكون نتيجته false إذا كانت جميع الشروط غير متحققة.

في التمرين 33، إذا كان value صادقًا، يتوقف التقييم وتُرجع الدالة القيمة نفسها. وإذا كان value كاذبًا، ينتقل التقييم إلى القيمة الثانية !!value، وهي false، فتُرجعها الدالة.

العامل OR || هل يُرجع قيمة غير true أو false؟

نعم، هذا سلوكه المقصود. || يُرجع أول قيمة صادقة، أو آخر قيمة إذا كانت جميع القيم كاذبة.

التمرين 34: أنشئ دالة تُرجع true إذا احتوت القيمة على "z"؛ وإلا فتُرجع false.

function isThereZ(value){
  return (value.indexOf("z") !== -1);
}

console.log(isThereZ("Hello everyone"));
console.log(isThereZ("zerro is here"));
console.log(isThereZ("He is going zzzzzzzzzz"));
console.log(isThereZ("Everyone is working here."));

النتيجة كما يلي:

false
true
true
false

ملاحظة

string.indexOf(character) تُرجع -1 إذا لم تحتوِ السلسلة على المحرف.

التمرين 35: أنشئ دالة تتحقّق من إدخال كلمة المرور؛ فتُرجعها إن كانت صادقة، وإلا تُرجع false.

function isPasswordProvided(password){
  return password || !!password;
}

console.log(isPasswordProvided("@jksd55"));
console.log(isPasswordProvided(null));
console.log(isPasswordProvided("123"));
console.log(isPasswordProvided(undefined));
console.log(isPasswordProvided(""));

النتيجة كما يلي:

@jksd55
false
123
false
false

التمرين 36: اقرأ الشيفرة التالية وحاول فهمها.

function somethingMissing(num){
  console.log(num)
}

somethingMissing();

النتيجة هي: undefined.

ماذا حدث؟ لم نُمرّر قيمة عند استدعاء الدالة. num لم تُسنَد إليه قيمة، لذا فهو undefined.

التمرين 37: تأمّل الشيفرة وحاول توقّع النتيجة.

function display(a, b, c, d){
  console.log(a, b, c, d);
}

display(1, 2, 3, 4);
display(6, 88);
display(77, 88, 99);
display(700);
display();

النتيجة كما يلي:

1 2 3 4
6 88 undefined undefined
77 88 99 undefined
700 undefined undefined undefined
undefined undefined undefined undefined

تذكّر!

undefined هي القيمة الافتراضية هنا عند عدم إسناد قيمة.

التمرين 38: اقرأ الشيفرة وحاول فهم النتيجة.

function display(a, b, c, d=1){
  console.log(a, b, c, d);
}

display(1, 2, 3, 4);
display(6, 88);
display(77, 88, 99);
display(700);
display();

النتيجة كما يلي:

1 2 3 4
6 88 undefined 1
77 88 99 1
700 undefined undefined 1
undefined undefined undefined 1

في التمرين 38؛ حدّدنا قيمة افتراضية للمعامل d. إذا لم تستدعِ الدالة display مع قيمة محدّدة لـ d ، فستظهر القيمة الافتراضية.

التمرين 39: أعد تنفيذ التمرين 38 وأضف قيمة افتراضية لـ cتساوي 5.

function display(a, b, c=5, d=1){
  console.log(a, b, c, d);
}

display(1, 2, 3, 4);
display(6, 88);
display(77, 88, 99);
display(700);
display();

النتيجة كما يلي:

1 2 3 4
6 88 5 1
77 88 99 1
700 undefined 5 1
undefined undefined 5 1

ما الدالة؟

الدالة كتلة شيفرة يمكن إعادة استخدامها مرات متعددة في البرنامج.

قد تستقبل الدالة معاملًا أو أكثر، وتعالج القيم لإنتاج قيمة مُرجعة.

يمكن استدعاء الدالة باسمها من المواضع التي تكون متاحة فيها ضمن النطاق.