MDN wants to learn about developers like you: https://qsurvey.mozilla.com/s3/MDN-dev-survey

This translation is incomplete. Please help translate this article from English.

جافاسكريبت تدعم مجموعة من البيانات المدمجة، وتحديدا التحكم في تدفق البيانات، التي يمكنك استخدامها لخلق قدرا كبيرا من التفاعل في التطبيق الخاص بك. يقدم هذا الفصل لمحة عامة عن هذه البيانات.

يحتوي هذا الفصل، مرجع الجافاسكريبت على تفاصيل شاملة عن التعليمات البرمجية. في جافاسكريبت، يتم استخدام رمز الفاصلة المنقوطة (;) لانهاء التعليمات البرمجية.

ملحوظة: برامج الجافاسكريبت وبيانات الجافاسكريبت، غالباً ما تسمى تعليمات برمجية.

أي تعبير جافا سكريبت، هو  أيضا تعليمة برمجية. راجع Expressions and operators  للحصول على معلومات كاملة حول التعبيرات.

Block statement

ابسط تعليمة برمجية هي التعليمة البرمجية بلوك  block، التي تستخدم لاحتواء مجموعة من التعليمات البرمجية. البلوك محدد بواسطة الاقواس المتعرجة:

{
  statement_1;
  statement_2;
  .
  .
  .
  statement_n;
}

مثال

اغلب استخدامات البلوك، مع تعليمات التحكم في التدفق ( مثل if, for, while )

while (x < 10) {
  x++;
}

لدينا هنا، {;x++ } التعليمة البرمجة block.

هام: في جافا سكريبت قبل ECMAScript2015. البلوك لم يكن لديه نطاق. المتغيرات المستخدمة في البلوك، سيتم تغيير نطاقها الى النطاق العام وهو السكريبت، فتصبح متغيرات عامة متاحة لجميع التعليمات البرمجية في السكريبت، اما اذا وجد البلوك داخل دالة سيتم تغيير نطاقها لهذه الدالة، وبالتالي ستصبح متغيرات محلية متاحة لهذه الدالة فقط.

في جافا سكريبت، البلوكات "المستقلة"  يمكن أن ينتج  عنها نتائج مختلفة تماما عما كان سينتج في C أو جافا. فمثلا

var x = 1;
{
  var x = 2;
}
console.log(x); // outputs 2

مخرجات التعليمة البرمجية اعلاه، ستكون 2 وذالك لان المتغير x المتواجد داخل البلوك والمتغير x المتواجد خارج البلوك لديهما نفس النطاق، او بمعنى اصح، كلاهما في النطاق العام وهو السكريببت. في C أو جافا. المخرجات ستكون 1.

ابتداءا من ECMAScript2015. استخدام المتغير let داخل البلوك سينتج عنه سلوك مغاير. راجع let صفحة المرجع للحصول على مزيد من المعلومات.

التعليمات الشرطية

التعليمة الشرطية هي مجموعة من الأوامر التي ستنفذ إذا تحقق شرطا معيناً. تدعم الجافاسكريبت اثنين من التعليمات الشرطية: هما if...else و switch.

التعليمة if...else

ستنفذ التعليمة البرمجية المرتبطة بالتعليمة if اذا كان الشرط المنطقي يساوي true. وكذالك ستنفذ التعليمة البرمجية المرتبطة بالتعليمة else اذا كان الشرط المنطقي يساوي false. استخدام التعليمة else اختياري. فيما تكون التعليمة if على الشكل التالي،

if (condition) {
  statement_1;
} else {
  statement_2;
}

الشرط condition، يمكن ان يكون اي تعبير لإختبار ما اذا كان الشرط true او false راجع Boolean. لتوضيح ما الذي سيتم تنفيذه: في حالة ما اذا كان الشرط صحيح  سيتم تنفيذ statement_1، اما اذا كان الشرط غير صحيح سيتم تنفيذ statement_2، يمكن ل statement_1 و statement_2 ان تكون اي تعليمات برمجية، بما فيها تعليمة if اخرى.

يمكنك أيضا توسيع مجال التعليمات الشرطية باستخدام else if لاختبار شروط متعددة في تسلسل، كما يلي:

if (condition_1) {
  statement_1;
} else if (condition_2) {
  statement_2;
} else if (condition_n) {
  statement_n;
} else {
  statement_last;
} 

في حالة وجود شروط متعددة سيتم تنفيذ شرط واحد فقط، وهو الشرط المنطقي الذي سيتم اختباره ب true. لتنفيذ عدة تعليمات برمجية، قم بتضمينها في التعليمة بلوك ({ ... }). من الجيد دائماً استخدام التعليمة بلوك، لا سيما عند استخدام التعليمات الشرطية المتداخلة :

if (condition) {
  statement_1_runs_if_condition_is_true;
  statement_2_runs_if_condition_is_true;
} else {
  statement_3_runs_if_condition_is_false;
  statement_4_runs_if_condition_is_false;
}
من المستحسن عدم استخدام التعيينات البسيطة في تعبير الشرطي، لأنه يمكن الخلط بين التعيين والمساواة، على سبيل المثال، لا تستخدم التالي:
 
if (x = y) {
  /* statements here */
}

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

if ((x = y)) {
  /* statements here */
}

القيم  Falsy

القيم التالية تُقَيًم إلى false عند اختباها في تعليمة شرطية (وتعرف ايضا بالقيم Falsy):

  • false
  • undefined
  • null
  • 0
  • NaN
  • السلسلة الحرفية الفارغة ("")

كل القيم الأخرى، بما في ذلك جميع الكائنات، تقيم إلى true عندما يتم تمريرها إلى تعليمة شرطية.

لا تخلط بين القيم المنطقية الاولية true و false مع القيم true و false للكائن Boolean. على سبيل المثال:

var b = new Boolean(false);
if (b) // this condition evaluates to true
if (b == true) // this condition evaluates to false

مثال

فى المثال التالى, الدالة checkData ستعود ب true ادا كان عدد الحروف في الكائن Text يساوي ثلاثة، بخلاف ذالك، ستظهر التنبيه (alert) وتعود ب false.

function checkData() {
  if (document.form1.threeChar.value.length == 3) {
    return true;
  } else {
    alert('Enter exactly three characters. ' +
    document.form1.threeChar.value + ' is not valid.');
    return false;
  }
}

التعليمة switch

التعليمة switch تسمح للبرنامج باختبار التعبير، وذالك من خلال مطابقة قيمة التعبير مع الحالة case. إذا تم العثور على تطابق، البرنامج سينفذ التعليمة البرمجية المرتبطة بها. التعليمة switch تكون على الشكل التالي:

switch (expression) {
  case label_1:
    statements_1
    [break;]
  case label_2:
    statements_2
    [break;]
    ...
  default:
    statements_def
    [break;]
}

بداية يقوم البرنامج بالبحث عن الحالة case التي تطابق قيمتها قيمة ال expression، اذا وجدت، يقوم البرنامج بتنفيذ التعليمة البرمجية المرتبطة بها، اذا لم يجد ما يبحث عنه في اي من الحالات case، سيقوم البرنامج بتنفيذ التعليمات البرمجية المرتبطة بالحالة default اذا وجدت، لان وجود الحالة default في التعليمة switch اختياري. اذا لم يجد البرنامج اي حالة case متطابقة ولا الحالة default سيقوم بتنفيذ التعليمات البرمجية التي تلي التعليمة switch.

التعليمة break مرتبطة مع كل حالة case، مهمتها جعل البرنامج يقفز خارج التعليمة switch بمجرد تنفيذ التعليمة البرمجية، واستكمال تنفيذ التعليمات البرمجية التي تلي التعليمة switch. بما ان وجود التعليمة break اختياري، ففي حالة عدم وجودها سيقوم البرنامج بتنفيذ التعليمة التالية في switch.

مثال

في المثال التالي، اذا كان fruittype يساوي "Bananas"،  سيقوم البرنامج بتنفيذ  التعليمات البرمجية المرتبطة بالحالة 'case: 'Banana. عندما سسيجد break، سيقوم بايقاف switch وينفذ التعليمات البرمجية التي تليها. اذا لم يجد break سينفذ التعليمة البرمجية المرتبطة بالحالة 'case: 'Cherries ايضا. 

switch (fruittype) {
  case 'Oranges':
    console.log('Oranges are $0.59 a pound.');
    break;
  case 'Apples':
    console.log('Apples are $0.32 a pound.');
    break;
  case 'Bananas':
    console.log('Bananas are $0.48 a pound.');
    break;
  case 'Cherries':
    console.log('Cherries are $3.00 a pound.');
    break;
  case 'Mangoes':
    console.log('Mangoes are $0.56 a pound.');
    break;
  case 'Papayas':
    console.log('Mangoes and papayas are $2.79 a pound.');
    break;
  default:
   console.log('Sorry, we are out of ' + fruittype + '.');
}
console.log("Is there anything else you'd like?");

ملاحظة : لمزيد من التفاصيل حول التعليمة  switch.

التعليمات المعالجة للاستثناءات

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

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

بصفة عامة، الاستثناءات هي عبارة عن آلية برمجية لمعالجة أخطاء التنفيذ المحتمل وقوعها.

 

يمكنك قذف (توليد)  الاستثناءات من خلال التعليمة throw والتعامل معها باستخدام التعليمة try...catch

انواع الاستثناءات

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

التعليمة throw

التعليمة throw تقذف الاخطاء. عند حدوث خطأ، عادة سوف تتوقف جافا سكريبت، وستولد رسالة للاعلان عن الخطأ. المصطلح التقني لهذه العملية هو : الجافاسكريبت ستقذف (throw) الخطأ. التعليمة throw تمكتك من انشاء خطأ حسب رغبتك. المصطلح التقني لهذه العملية هو: اقذف استثناءا (throw an exception).

إستخدِم التعليمة throw لقذف الإستثناء، عنما تريد قذف إستثناءا، عليك تحديد التعبير (expression) الذي سيحتوي على القيمة التي ستقذف:

throw expression;

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

throw 'Error2';   // String type
throw 42;         // Number type
throw true;       // Boolean type
throw {toString: function() { return "I'm an object!"; } };
ملحوظة : يمكنك تحديد كائن عندما ستقوم بقذف الاستثناء. يمكنك بعد ذالك الاشارة إلى خصائص الكائن في البلوك catch. يقوم المثال التالي بإنشاء الكائن myUserException من النوع UserException واستحدامه في التعليمة throw.
// Create an object type UserException
function UserException(message) {
  this.message = message;
  this.name = 'UserException';
}

// Make the exception convert to a pretty string when used as a string
// (e.g. by the error console)
UserException.prototype.toString = function() {
  return this.name + ': "' + this.message + '"';
}

// Create an instance of the object type and throw it
throw new UserException('Value too high');

لمزيد من المعلومات حول هذه التعليمة، راجع صفحة مرجع الجافا سكريبت  throw.

التعليمة try...catch

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

التعليمة try...catch تتكون من البلوك try الذي سيحتوي على واحدة أو أكثر من التعليمات البرمجية، والبلوك catch سيحتوي على التعليمات البرمجية التي تحدد ما يجب فعله اذا تم قذف الاستثناء من البلوك try. بمعنى اخر، في معظم الحالات. نريد من التعليمات البرمجية داخل البلوك try ان تسير بشكل طبيعي، وفي حالة حدوث مشاكل يمرّر التحكم الى البلوك catch. إذا كانت هناك احدى التعليمات البرمجية داخل البلوك try تقذف استثناءا، سيتم نقل التحكم فورا إلى البلوك catch. وإذا لم يتم إرسال أي استثناء من داخل البلوك try، فالبلوك catch لن يقم باي شئ. هذه التعليمة البرمجية يمكن ان تحتوي على البلوك finally والذي سينفذ بعد تنفيذ البلوك  try و catch، وايضا سينفذ قبل تنفيذ التعليمات البرمجية التي تلي التعليمة try...catch، اذا وجدت.


المثال التالى يستخدم التعليمة try...catch. ويقوم باستدعاء دالة تعود باسم الشهر من مصفوفة بناء على القيمة التي تم تمريرها إلى الدالة. إذا كانت القيمة لا تتوافق مع رقم الشهر (1-12)، سيولّد استثناء مع القيمة "InvalidMonthNo" فيما تقوم التعليمة البرمجية في البلوك catch بتعين القيمة unknown إلى المتغير monthName.

function getMonthName(mo) {
  mo = mo - 1; // Adjust month number for array index (1 = Jan, 12 = Dec)
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
                'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
  if (months[mo]) {
    return months[mo];
  } else {
    throw 'InvalidMonthNo'; //throw keyword is used here
  }
}

try { // statements to try
  monthName = getMonthName(myMonth); // function could throw exception
}
catch (e) {
  monthName = 'unknown';
  logMyErrors(e); // pass exception object to error handler -> your own function
}

The catch block

يمكنك استخدام البلوك  catch للامساك بجميع الاستثناءات التي تسيتم قذفها من البلوك try.

catch (catchID) {
  statements
}

البلوك catch يحدد الايدي catchID الذي سيمسك القيمة المحددة من طرف التعليمة throw، يمكنك استخدام هذا الايدي للحصول على معلومات حول الاستثناء الذي سيقذف. جافا سكريبت ستنشئ هذا الايدي عند دخوله الى البلوك catch. يبدا عمر هذا الايدي من لحظة دخوله الى البلوك catch، وينتهي عندما ينتهي البلوك catch من التنفيذ.

على سبيل المثال، التعليمة البرمجية التالية ستقذف استثناءا. عند حدوث الاستثناء، سيتم نقل التحكم الى البلوك catch.

try {
  throw 'myException'; // generates an exception
}
catch (e) {
  // statements to handle any exceptions
  logMyErrors(e); // pass exception object to error handler
}

The finally block

البلوك finally سيحتوي على التعليمات البرمجية التي سيقوم بتنفيذها بعدما تنفذ البلوكات try و catch، وايضا سينفذ قبل تنفيذ التعليمات البرمجية التي تلي التعليمة try...catch. سينفذ البلوك finally سواء تم قذف الاستثناء ام لا، اذا تم قذف الاستثناء، ستنفذ التعليمات البرمجية في البلوك finally حتى وان لم يتم معالجة الاستثناء في البلوك catch.

يمكنك استخدام البلوك finally لجعل السكريبت الخاص بك يفشل بأمان عند حدوث استثناء، على سبيل المثال، اذا كنت في حاجة إلى تحرير مورد، او لغلق ال flux، الخ. المثال التالي يفتح ملف ثم ينفذ التعليمات البرمجية لهذا ملف (server-side JavaScript يسمح لك بالوصول الى الملفات). اذا تم قذف استثناء في حين أن الملف مفتوح، البلوك finally ستغلق هذا الملف قبل فشل السكريبت.

openMyFile();
try {
  writeMyFile(theData); //This may throw a error
} catch(e) {
  handleError(e); // If we got a error we handle it
} finally {
  closeMyFile(); // always close the resource
}

عندما سيقوم البلوك finally بارجاع قيمة، تصبح هذه القيمة قيمة الإرجاع من كامل المجموعة  try-catch-finally بغض النظر عن التعليمات البرمجية العائدة من البلوكات  try و catch.

function f() {
  try {
    console.log(0);
    throw 'bogus';
  } catch(e) {
    console.log(1);
    return true; // this return statement is suspended
                 // until finally block has completed
    console.log(2); // not reachable
  } finally {
    console.log(3);
    return false; // overwrites the previous "return"
    console.log(4); // not reachable
  }
  // "return false" is executed now
  console.log(5); // not reachable
}
f(); // console 0, 1, 3; returns false

الكتابة فوق القيم العائدة من قبل البلوك finally ينطبق أيضا على قذف الاستثناءات او اعادة القذف داخل البلوك catch:

function f() {
  try {
    throw 'bogus';
  } catch(e) {
    console.log('caught inner "bogus"');
    throw e; // this throw statement is suspended until
             // finally block has completed
  } finally {
    return false; // overwrites the previous "throw"
  }
  // "return false" is executed now
}

try {
  f();
} catch(e) {
  // this is never reached because the throw inside
  // the catch is overwritten
  // by the return in finally
  console.log('caught outer "bogus"');
}

// OUTPUT
// caught inner "bogus"

التعليمات try...catch المتداخلة

يمكن عمل واحدة او اكثر من التعليمات try...catch المتداخلة.  شرط عدم توفر try...catch الداخلية على البلوك catch، تتطلب وجود البلوك finally والتعليمة try...catch الخارجية سوف تستخدم البلوك catch ليتم التحقق من المطابقة. راجع nested try-blocks في صفحة المرجع الخاص بالتعليمة try...catch.

باستخدام الكائنات Error

اعتماداً على نوع الخطأ، من الممكن استخدام الخصائص name و message للحصول على رسالة أكثر دقة. عموما لدينا الخاصية name التي ستعرض نوع الخطا الذي حدث (مثلا: DOMException او Error). والخاصية message التي ستعرض رسالة الخطأ لوصف هذا الخطا (تستخدم عادة عندما نريد تحويل او عرض نص الخطأ). على سبيل المثال:

try {
  throw new Error('Whoops!');
} catch (e) {
	if( e.message === 'Whoops!'){
		e.message = "Costume message";
	}
  console.log(e.name + ': ' + e.message); // Error: Costume message
}

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

function doSomethingErrorProne() {
  if (ourCodeMakesAMistake()) {
    throw (new Error('The message'));
  } else {
    doSomethingToGetAJavascriptError();
  }
}
....
try {
  doSomethingErrorProne();
} catch (e) {
  console.log(e.name); // logs 'Error'
  console.log(e.message); // logs 'The message' or a JavaScript error message)
}

Promises

ابتداءا من ECMAScript2015. اصبح لجافاسكريبت الكائن Promise والذي يسمح لك بالتحكم في التدفق والعمليات المتزامنة.

Promise هو احد هذه الحالات:

  • pending  (قيد الانتظار): الحالة الأولية، لم تَفِ أو تم رفضها.
  • fulfilled  (وفَّى): عملية ناجحة
  • rejected  (رُفِض): فشل العملية.
  • settled  (التسوية): إما وفى بوعد أو رفضه، ولكن ليس قيد الانتظار.

تحميل صورة ب XHR

مثال بسيط باستخدام Promise و XMLHttpRequest مثال بسيط باستخدام Promise في مستودع الاكواد MDN GitHub. راجع المثال js-examples. يمكنك ايضا مراجعة see it in action. تم التعليق على كل خطوة لتمكينك من متابعة سير عملية Promise و XHR. هذا الإصدار من دون تعليقات، يعرض تدفق ال Promise:

function imgLoad(url) {
  return new Promise(function(resolve, reject) {
    var request = new XMLHttpRequest();
    request.open('GET', url);
    request.responseType = 'blob';
    request.onload = function() {
      if (request.status === 200) {
        resolve(request.response);
      } else {
        reject(Error('Image didn\'t load successfully; error code:'
                     + request.statusText));
      }
    };
    request.onerror = function() {
      reject(Error('There was a network error.'));
    };
    request.send();
  });
}

للحصول على معلومات أكثر تفصيلاً، راجع Promise في صفحة المرجع.

Document Tags and Contributors

 Contributors to this page: Youssef-Belmeskine
 Last updated by: Youssef-Belmeskine,