throw في JavaScript

من موسوعة حسوب
اذهب إلى: تصفح، ابحث

التعبير البرمجي throw يؤدي إلى رمي استثناء (exception) يُعرِّفه المستخدم، وسيؤدي ذلك إلى توقف تنفيذ الدالة الحالية (أي أنَّ التعابير البرمجية بعد throw لن تُنفَّذ) وسينتقل التنفيذ إلى أوّل catch، وإذا لم تكن موجودةً فسينتهي تنفيذ البرنامج.

البنية العامة

throw expression;

expression

التعبير الذي سيُرمى.

الوصف

يُستخدَم التعبير throw لرمي استثناء، وعندما ترمي استثناءً فإنَّ قيمة expression تُحدِّد ما هي قيمة الاستثناء. أمثلة:
throw 'Error2'; // توليد استثناء له قيمة نصية
throw 42;       // توليد استثناء له قيمة عددية
throw true;     // توليد استثناء له قيمة منطقية
لاحظ أنَّ التعبير throw يتأثر بالإضافة التلقائية للفواصل المنقوطة، لذا لا يجوز وضع سطر فارغ بين الكلمة المحجوزة throw والتعبير.

أمثلة

رمي كائن

يمكنك رمي كائن كاستثناء، ويمكنك بعد ذلك أن تُشير إلى خصائص ذلك الكائن في قسم catch، لاحظ كيف أنشأنا الكائن UserException في المثال الآتي ثم رميناه عبر التعبير throw:
function UserException(message) {
   this.message = message;
   this.name = 'UserException';
}
function getMonthName(mo) {
   mo = mo - 1; // (1 = Jan, 12 = Dec)
   var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
      'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
   if (months[mo] !== undefined) {
      return months[mo];
   } else {
      throw new UserException('InvalidMonthNo');
   }
}

try {
   var myMonth = 15; // رقم خارج النطاق المسموح
   var monthName = getMonthName(myMonth);
} catch (e) {
   monthName = 'unknown';
   console.log(e.message, e.name); // تمرير الكائن إلى err
}

مثال آخر عن رمي كائن

هذا المثال يختبر سلسلة نصية إذا كانت تُطابِق كود zip في الولايات المتحدة، وإذا لم تكن صيغة الكود صحيحة، فسيرمى استثناءٌ بإنشاء كائنٍ من النوع ZipCodeFormatException:
/*
 * إنشاء كائن ZipCode.
 *
 * الصيغ المسموحة لكود zip:
 *    12345
 *    12345-6789
 *    123456789
 *    12345 6789
 *
 * إذا لم تكن السلسلة النصية الممررة للدالة
 * مطابقةً لأحد الأنماط السابقة، فسيرمى استثناء
 */

function ZipCode(zip) {
   zip = new String(zip);
   pattern = /[0-9]{5}([- ]?[0-9]{4})?/;
   if (pattern.test(zip)) {
      this.value = zip.match(pattern)[0];
      this.valueOf = function() {
         return this.value
      };
      this.toString = function() {
         return String(this.value)
      };
   } else {
      throw new ZipCodeFormatException(zip);
   }
}

function ZipCodeFormatException(value) {
   this.value = value;
   this.message = 'does not conform to the expected format for a zip code';
   this.toString = function() {
      return this.value + this.message;
   };
}

/*
 * التحقق من كود zip 
 * في العناوين في الولايات المتحدة
 */

const ZIPCODE_INVALID = -1;
const ZIPCODE_UNKNOWN_ERROR = -2;

function verifyZipCode(z) {
   try {
      z = new ZipCode(z);
   } catch (e) {
      if (e instanceof ZipCodeFormatException) {
         return ZIPCODE_INVALID;
      } else {
         return ZIPCODE_UNKNOWN_ERROR;
      }
   }
   return z;
}

a = verifyZipCode(95060);         // 95060
b = verifyZipCode(9560);          // -1
c = verifyZipCode('a');           // -1
d = verifyZipCode('95060');       // 95060
e = verifyZipCode('95060 1234');  // 95060 1234

إعادة رمي الاستثناء

يمكنك استخدام التعبير throw لإعادة رمي الاستثناء، ففي المثال الآتي سنحاول معالجة استثناء له قيمة رقمية عبر قسم catch، وإذا كانت قيمة ذلك الاستثناء أكبر من 50 فسنعيد رميه مرةً أخرى لكي تُعالِجَه الدالة أو ليراه المستخدم:
try {
   throw n; // رمي استثناء له قيمة رقمية
} catch (e) {
   if (e <= 50) {
      // تعابير برمجية لمعالجة القيمة من 1 -50
   } else {
      // لا يمكننا معالجة الاستثناء، لذا سنعيد رميه
      throw e;
   }
}

دعم المتصفحات

الميزة Chrome Firefox Internet Explorer Opera Safari
الدعم الأساسي نعم نعم نعم نعم نعم

مصادر ومواصفات