الكلمات السابقة
تعتبر معالجة الأخطاء أمرًا بالغ الأهمية لتطوير تطبيقات الويب. لا يمكن أن يتنبأ بالأخطاء المحتملة مقدمًا ، ولا يمكن اعتماد استراتيجيات الاسترداد مقدمًا ، مما قد يؤدي إلى ضعف تجربة المستخدم. نظرًا لأن أي خطأ في JavaScript يمكن أن يتسبب في أن تكون صفحة الويب غير صالحة للاستعمال ، كمطور ، يجب أن تعرف متى ولماذا وماذا سيحدث. ستقدم هذه المقالة آلية معالجة الأخطاء في JavaScript بالتفصيل
كائن الخطأ
كائن الخطأ هو كائن يحتوي على معلومات الخطأ وهو كائن أصلي لـ JavaScript. عندما يحدث خطأ أثناء تحليل الكود أو تشغيله ، سيقوم محرك JavaScript تلقائيًا بإنشاء مثيل لكائن الخطأ ورميه تلقائيًا ، ثم يتم مقاطعة البرنامج بأكمله عند حدوث الخطأ.
console.log (t) ؛ // uncaughtederror: t غير محدد
تحدد ECMA-262 أن كائن خطأ يتضمن خصائصين: الرسالة والاسم. تحفظ سمة الرسالة رسالة الخطأ ، بينما تحفظ سمة الاسم نوع الخطأ
نسخة الكود كما يلي:
// عمومًا ، استخدم عبارة Try-Catch لالتقاط الأخطاء
يحاول{
ر ؛
} catch (ex) {
console.log (ex.message) ؛ // t غير محدد
console.log (ex.name) ؛ // Referenceerror
}
قام المتصفح أيضًا بتوسيع خصائص كائن الخطأ وأضاف المعلومات الأخرى ذات الصلة. من بينها ، أكثر شركات تصنيع المستعرضات تنفيذها هي سمة المكدس ، والتي تشير إلى معلومات تتبع المكدس (لا تدعمها Safari)
نسخة الكود كما يلي:
يحاول{
ر ؛
} catch (ex) {
console.log (ex.stack) ؛ //@file: /// d: /wamp/www/form.html: 12: 2
}
بالطبع ، يمكنك استخدام مُنشئ ERROR () لإنشاء كائن خطأ. إذا تم تحديد معلمة الرسالة ، فسيستخدمها كائن الخطأ كخاصية للرسالة ؛ إذا لم يتم تحديدها ، فسيستخدم سلسلة افتراضية محددة مسبقًا كقيمة للخاصية
نسخة الكود كما يلي:
خطأ جديد () ؛
خطأ جديد (رسالة) ؛
// بشكل عام ، استخدم بيان رمي لرمي الأخطاء
رمي خطأ جديد ("اختبار") ؛ // خطأ غير معلوم: اختبار
رمي خطأ جديد () ؛ // خطأ غير معلوم
نسخة الكود كما يلي:
وظيفة usererror (رسالة) {
this.message = رسالة ؛
this.name = "usererror" ؛
}
userRerror.prototype = خطأ جديد () ؛
usererror.prototype.constructor = userRorror ؛
رمي المستخدم الجديد ("errormessage")
عندما يتم استدعاء مُنشئ الخطأ () مباشرة مثل وظيفة دون استخدام المشغل الجديد ، فإن سلوكه هو نفسه عندما يتم استدعاء المشغل الجديد
نسخة الكود كما يلي:
خطأ()؛
خطأ (رسالة) ؛
قم برمي الخطأ ("اختبار") ؛ // خطأ غير معلوم: اختبار
رمي خطأ () ؛ // خطأ غير معطل
يحتوي كائن الخطأ على طريقة TOSTRING () ، والتي تُرجع سمة الرسالة لكائن الخطأ.
نسخة الكود كما يلي:
var test = خطأ جديد ('testerror') ؛
console.log (test.toString ()) ؛ // "خطأ: Testerror"
نوع الخطأ
هناك العديد من أنواع الأخطاء التي قد تحدث أثناء تنفيذ الكود. كل خطأ له نوع خطأ مقابل ، وعندما يحدث خطأ ، سيتم طرح كائن خطأ من النوع المقابل. يحدد ECMA-262 أنواع الأخطاء السبعة التالية:
نسخة الكود كما يلي:
خطأ
evalerror (خطأ eval)
Rangeerror (Rangeerror)
مرجع (خطأ مرجعي)
بناء الجملة (خطأ في بناء الجملة)
Typeerror (خطأ في النوع)
urierror (خطأ URI)
أينما ، يكون الخطأ هو النوع الأساسي ، وترث أنواع الأخطاء الأخرى من هذا النوع. لذلك ، تشترك جميع أنواع الأخطاء في مجموعة من نفس الخصائص. أخطاء نوع الخطأ نادرة ، وإذا كان هناك ، يتم إلقاؤها أيضًا من قبل المتصفح ؛ الغرض الرئيسي من هذا النوع الأساسي هو للمطورين رمي أخطاء مخصصة
【evalerror (خطأ في تقييم)】
عندما لا يتم تنفيذ وظيفة eval بشكل صحيح ، سيتم إلقاء خطأ evalerror. لم يعد نوع الخطأ هذا يظهر في ES5 ، ولكن سيتم الحفاظ عليه لضمان التوافق مع الرموز السابقة.
【RangeError (RangeError)】
سيتم تشغيل خطأ في نوع RangeError عندما تتجاوز القيمة النطاق المقابل ، بما في ذلك تجاوز نطاق طول الصفيف وتجاوز نطاق قيمة الأرقام.
نسخة الكود كما يلي:
صفيف جديد (-1) ؛ // uncagetror rangeerror: طول صفيف غير صالح
صفيف جديد (رقم
(1234). toxponential (21) ؛ // unciction Rangeerror: يجب أن تكون الوسيطة toexponential () ما بين 0 و 20
(1234). toxponential (-1) ؛ //// uncaughter Rangeerror: يجب أن تكون الوسيطة toexponential () ما بين 0 و 20
【ReferenceerRor (خطأ مرجعي)】
سيتم تشغيل ReferenceerRor عند الإشارة إلى خطأ متغير غير ثابت أو نوع LVALUE.
أ ؛
1++
【Syntaxerror (Syntaxerror)】
عندما لا يتم استيفاء قواعد بناء الجملة ، سيتم طرح بناء جملة (خطأ في بناء الجملة)
نسخة الكود كما يلي:
// الاسم المتغير خاطئ
var 1a ؛ // syntaxerror unciture: رقم غير متوقع
// الأقواس المفقودة
console.log 'hello') ؛ // unticated syntaxerror: سلسلة غير متوقعة
【typeerror (خطأ في النوع)】
سيتسبب خطأ نوع Typeerror عند تخزين أنواع غير متوقعة في المتغيرات ، أو عند الوصول إلى طرق غير موجودة. على الرغم من أن أسباب الأخطاء متنوعة ، في النهاية ، فذلك لأن نوع المتغير لا يفي بالمتطلبات عند إجراء نوع محدد من التشغيل.
نسخة الكود كما يلي:
var o = new 10 ؛ // uniticed typeerror: 10 ليس مُنشئًا
تنبيه ("الاسم" في true) ؛ // uncaught typeerror: لا يمكن استخدام "في" المشغل للبحث عن "الاسم" في True
function.prototype.toString.call ('name')
【urierror (خطأ URI)】
Urierror هو خطأ يتم إلقاؤه عندما تكون معلمات الوظائف المتعلقة باليوري غير صحيحة. يتضمن بشكل أساسي ست وظائف: Encodeuri () ، decodeuri () ، EncodeUricomponent () ، decodeuricomponent () ، Escape () و unescape ().
decodeuri ('٪ 2') ؛ // urierror: URI مشوه
حدث الخطأ
أي أخطاء لا تتم معالجتها من خلال Try-Catch ستؤدي إلى حدوث حدث خطأ في كائن النافذة
يمكن أن يتلقى حدث الخطأ ثلاث معلمات: رسالة خطأ ، عنوان URL حيث يوجد الخطأ ، ورقم السطر. في معظم الحالات ، تكون رسائل الخطأ فقط مفيدة لأن عنوان URL يعطي موقع المستند فقط ، ويشير رقم السطر إلى سطر من التعليمات البرمجية التي يمكن أن تكون من رمز JavaScript المضمن أو من ملف خارجي.
لتحديد معالج حدث خطأ ، يمكنك استخدام تقنية مستوى DOM0 أو استخدام التنسيق القياسي لأحداث مستوى DOM2
نسخة الكود كما يلي:
// مستوى DOM0
window.onerror = وظيفة (الرسالة ، URL ، السطر) {
تنبيه (رسالة) ؛
}
// مستوى DOM2
Window.AdDeventListener ("خطأ" ، وظيفة (الرسالة ، URL ، السطر) {
تنبيه (رسالة) ؛
}) ؛
ما إذا كان المتصفح يعرض رسالة خطأ قياسية تعتمد على قيمة إرجاع Onerror. إذا كانت قيمة الإرجاع خاطئة ، فسيتم عرض رسالة خطأ في وحدة التحكم ؛ إذا كانت قيمة الإرجاع صحيحة ، فلا يتم عرضها
نسخة الكود كما يلي:
// يعرض وحدة التحكم رسالة الخطأ
window.onerror = وظيفة (الرسالة ، URL ، السطر) {
تنبيه (رسالة) ؛
العودة كاذبة
}
أ ؛
// وحدة التحكم لا تعرض رسالة الخطأ
window.onerror = وظيفة (الرسالة ، URL ، السطر) {
تنبيه (رسالة) ؛
العودة صحيح.
}
أ ؛
معالج الحدث هذا هو خط الدفاع الأخير لتجنب أخطاء الإبلاغ عن المتصفح. من الناحية المثالية ، يجب ألا تستخدمه كلما كان ذلك ممكنًا. طالما أنه يمكنك استخدام بيان المحاولة بشكل مناسب ، فلن تكون هناك أخطاء تم تسليمها إلى المتصفح ولن يتم تشغيل حدث الخطأ.
تؤيد الصورة أيضًا أحداث الخطأ. طالما أن عنوان URL في خاصية SRC للصورة لا يمكنه إرجاع تنسيق الصورة المعترف به ، سيتم تشغيل حدث خطأ. في هذا الوقت ، يتبع حدث الخطأ تنسيق DOM ويعيد كائن حدث يستهدف الصورة كهدف
يظهر مربع تحذير عند تحميل الصورة. عند حدوث حدث خطأ ، انتهت عملية تنزيل الصورة ، مما يعني أنه لا يمكن تنزيله مرة أخرى.
نسخة الكود كما يلي:
var image = new image () ؛
Image.Src = 'Smilex.gif' ؛
image.onerror = function (e) {
console.log (e) ؛
}
رمي البيان ورمي الخطأ
يتم استخدام بيان الرمي لرمي خطأ. عند إلقاء خطأ ، يجب عليك تحديد قيمة لبيان الرمي. ما نوع هذه القيمة؟ لا يوجد شرط.
[ملاحظة] يتم حظر عملية رمي خطأ ، ولن يتم تنفيذ التعليمات البرمجية اللاحقة
نسخة الكود كما يلي:
رمي 12345 ؛
رمي "Hello World" ؛
رمي صحيح
رمي {name: 'javaScript'} ؛
يمكنك استخدام بيان الرمي لرمي كائن خطأ يدويًا
نسخة الكود كما يلي:
رمي خطأ جديد ("حدث شيء سيء") ؛
رمي SyntaxerRor جديد ('أنا لا أحب بناء الجملة الخاص بك.') ؛
رمي typeerror الجديد ('ما نوع المتغير الذي تأخذني من أجله؟') ؛
رمي New RangeError ("آسف ، ليس لديك فقط/" T لديك النطاق ".) ؛
رمي evalerror جديد ('هذا لا يقييم.') ؛
رمي urierror الجديد ('uri ، هل هذا أنت؟') ؛
قم بإلقاء مرجعية جديدة ("أنت لم تذكر/" ر استشهد مراجعك بشكل صحيح ") ؛
يمكن أن يؤدي استخدام سلاسل النموذج الأولي أيضًا إلى إنشاء أنواع خطأ مخصصة عن طريق وراثة خطأ (يتم تقديم سلاسل النموذج الأولي في الفصل 6). في هذه المرحلة ، تحتاج إلى تحديد سمات الاسم والرسائل لنوع الخطأ الذي تم إنشاؤه حديثًا
يعامل المتصفح أنواع الأخطاء المخصصة المخصصة من الخطأ تمامًا مثل أنواع الأخطاء الأخرى. يعد إنشاء خطأ مخصص مفيدًا إذا كنت تريد التقاط الخطأ الذي ترميه وعلاجه بشكل مختلف عن خطأ المتصفح.
نسخة الكود كما يلي:
وظيفة customerror (رسالة) {
this.name = 'customerror' ؛
this.message = رسالة ؛
}
customerror.prototype = خطأ جديد () ؛
رمي Customerror جديد ('رسالتي') ؛
عند مواجهة بيان رمي ، سيتوقف الرمز على الفور. سيستمر الكود في التنفيذ فقط إذا قامت عبارة تجرب بتقاط القيمة التي تم إلقاؤها.
التفسير الأكثر تفصيلاً هو: عندما يتم طرح استثناء ، سيتوقف مترجم JavaScript على الفور من المنطق الذي يتم تنفيذه حاليًا ويقفز إلى معالج الاستثناء القريب. يتم كتابة معالج الاستثناء في بند الصيد من عبارة المحاولة. إذا كان كتلة الكود التي ترمي الاستثناء لا تحتوي على شرط الصيد المرتبط ، فسيقوم المترجم بالتحقق من كتلة التعليمات البرمجية المغلقة على المستوى الأعلى لمعرفة ما إذا كان لديه معالج استثناء مرتبط. وهكذا حتى يتم العثور على معالج الاستثناء. إذا كانت الوظيفة التي ترمي الاستثناء لا تتعامل مع بيان التجربة الخاص بها ، فسيتم نشر الاستثناء لأعلى إلى الكود الذي يستدعي الوظيفة. وبهذه الطريقة ، سيتم نشر الاستثناء لأعلى على طول الهيكل المعجمي لطريقة JavaScript ومكدس الاتصال. إذا لم يتم العثور على معالج استثناء ، فسوف يتعامل JavaScript مع الاستثناء كخطأ في البرنامج وإبلاغه بالمستخدم
جرب بيان الصيد والقبض على خطأ
يقدم ECMA-262 Edition 3 عبارة Try-Catch كطريقة قياسية للتعامل مع الاستثناءات في JavaScript ، وتستخدم للقبض على الأخطاء والتعامل معها
من بينها ، يحدد جملة Try Clause كتلة التعليمات البرمجية حيث توجد الاستثناءات التي يجب معالجتها. يتبع جملة Catch جملة Try. عندما يحدث استثناء في مكان ما في كتلة المحاولة ، يتم استدعاء منطق الكود داخل الصيد. يتبع شرط الصيد الكتلة أخيرًا ، حيث يتم وضع رمز التنظيف. بغض النظر عما إذا كان هناك استثناء في كتلة المحاولة ، سيتم دائمًا تنفيذ المنطق داخل الكتلة أخيرًا. على الرغم من أن الصيد وأخيراً اختياري ، فإن بند المحاولة يتطلب واحدة على الأقل من الاثنين لتشكيل بيان كامل معها.
يجب أن تكون جميع كتل البيان Try/Catch/أخيرًا محاطة بأقواس مجعد. الأقواس هنا مطلوبة. حتى لو كان هناك بيان واحد فقط في البند ، فلا يمكن حذف الأقواس المجعد.
يحاول{
// بشكل عام ، سيبدأ الرمز هنا من البداية إلى النهاية دون أي مشاكل
// ولكن في بعض الأحيان يتم إلقاء استثناء ، إما إلقاؤه مباشرة ببيان الرمي أو بشكل غير مباشر عن طريق استدعاء طريقة
} catch (e) {
// إذا وفقط إذا تم طرح استثناء من خلال كتلة TRAW ، سيتم تنفيذ الرمز هنا
// هنا يمكنك الحصول على مرجع إلى كائن الخطأ أو القيم الأخرى التي يلقيها المتغير المحلي ه
// يمكن أن تعالج كتلة التعليمات البرمجية هنا هذا الاستثناء لسبب ما ، أو تجاهل هذا الاستثناء ، ويمكنها أيضًا إعادة تقديم الاستثناء من خلال بيان الرمي
} أخيراً{
// بغض النظر عما إذا كان بيان المحاولة يلقي استثناءً ، سيتم دائمًا تنفيذ المنطق في النهاية. الطرق لإنهاء كتلة عبارة المحاولة هي:
// 1. إنهاء بشكل طبيعي ، قم بتنفيذ البيان الأخير من كتلة البيان
// 2. قم بإنهاء بيان الاستراحة أو الاستمرار أو الإرجاع
// 3. رمي استثناء ، يتم اكتشاف الاستثناء من قبل بند الصيد
// 4. رمي استثناء ، لا يتم القبض على الاستثناء ، لا يزال يتم نشره لأعلى
}
بشكل عام ، ضع جميع الكود الذي قد يرمي أخطاء في كتلة TRIN
في حالة حدوث أي رمز في حظر TRALH ، سيتم الخروج على الفور عملية تنفيذ الكود وسيتم تنفيذ كتلة الصيد. في هذا الوقت ، ستتلقى كتلة الصيد كائنًا مع رسالة خطأ. ستختلف المعلومات الفعلية الواردة في هذا الكائن من المتصفح إلى المتصفح ، ولكن الشائع هو أن هناك سمة رسالة تخزن رسالة الخطأ
[ملاحظة] تأكد من تسمية كائن الخطأ. إذا إفراغه ، سيتم الإبلاغ عن خطأ في بناء الجملة.
نسخة الكود كما يلي:
يحاول{
س.
} catch (خطأ) {
التنبيه (خطأ. message) ؛ // Q غير محدد
}
// Syntaxerror غير المتوقعة: رمز غير متوقع)
يحاول{
س.
}يمسك(){
تنبيه (خطأ. message) ؛
}
تقبل Catch معلمة تشير إلى القيمة التي ألقيتها كتلة رمز المحاولة
نسخة الكود كما يلي:
وظيفة رمي (استثناء) {
يحاول {
رمي الاستثناء
} catch (e) {
console.log ('chaught:'+ e) ؛
}
}
رمي (3) ؛ // تم القبض عليه: 3
رمي ('hello') ؛ // تم القبض عليه: مرحبًا
رمي (خطأ جديد ("حدث خطأ"))) ؛ // صيد: خطأ: حدث خطأ
بعد أن يمسك كتلة رمز الصيد بالخطأ ، لن يتم مقاطعة البرنامج وسيستمر في التنفيذ وفقًا للعملية العادية.
نسخة الكود كما يلي:
يحاول{
رمي "خطأ" ؛
} catch (e) {
console.log (111) ؛
}
console.log (222) ؛
// 111
// 222
من أجل التقاط أنواع مختلفة من الأخطاء ، يمكن إضافة بيانات الحكم إلى كتلة رمز الصيد
نسخة الكود كما يلي:
يحاول {
foo.Bar () ؛
} catch (e) {
if (e extuteof evalerror) {
console.log (e.name + ":" + e.message) ؛
} آخر إذا (e extuteof rangeerror) {
console.log (e.name + ":" + e.message) ؛
}
// ...
}
على الرغم من أن البند الأخير اختياري في بيان المحاولة ، بمجرد استخدام البند الأخير ، سيتم تنفيذ رمزه بغض النظر عن السبب. وبعبارة أخرى ، يتم تنفيذ جميع الكود في كتلة TRAW بشكل طبيعي ، وسيتم تنفيذ الجمل أخيرًا ؛ إذا تم تنفيذ كتلة بيان catch بسبب خطأ ، فسيظل يتم تنفيذ الشرط الأخير. طالما أن الكود يحتوي على بنود أخيرًا ، بغض النظر عن الرمز الموجود في كتلة Try أو Catch - أو حتى عبارة الإرجاع ، فلن يتم منع تنفيذ البند أخيرًا.
نسخة الكود كما يلي:
// لم يتم القبض على الخطأ لأنه لا يوجد كتلة بيان الصيد. بعد تنفيذ كتلة الكود أخيرًا ، سيتم مقاطعة البرنامج حيث يتم إلقاء الخطأ.
وظيفة cleansup () {
يحاول {
رمي خطأ جديد ('خطأ ...') ؛
console.log ('لن يتم تنفيذ هذا الخط ") ؛
} أخيراً {
console.log ("عمل التنظيف الكامل") ؛
}
}
cleansup () ؛
// أكمل أعمال التنظيف
// خطأ: حدث خطأ ما ...
نسخة الكود كما يلي:
وظيفة testfinnally () {
يحاول{
العودة 2 ؛
} catch (خطأ) {
العودة 1 ؛
} أخيراً{
العودة 0 ؛
}
}
testfinnally () ؛ // 0
[ملاحظة] يتم الحصول على قيمة عدد عبارة الإرجاع قبل تشغيل كتلة الرمز أخيرًا.
نسخة الكود كما يلي:
var count = 0 ؛
وظيفة countup () {
يحاول {
عدد العائد
} أخيراً {
count ++ ؛
}
}
countup () ؛ // 0
console.log (count) ؛ // 1
نسخة الكود كما يلي:
وظيفة f () {
يحاول {
console.log (0) ؛
رمي "علة" ؛
} catch (e) {
console.log (1) ؛
العودة صحيح. // قد تأخرت هذه الجملة حتى نهاية كتلة الكود أخيرًا قبل التنفيذ
console.log (2) ؛ // لن يعمل
} أخيراً {
console.log (3) ؛
العودة كاذبة // ستغطي هذه الجملة العائد السابق
console.log (4) ؛ // لن يعمل
}
console.log (5) ؛ // لن يعمل
}
var result = f () ؛
// 0
// 1
// 3
console.log (نتيجة) ؛ // خطأ
【نصائح】 نطاق مستوى الكتلة
يتمثل أحد الاستخدامات الشائعة لبيانات التجربة في إنشاء نطاقات على مستوى الكتلة حيث تكون المتغيرات المعلنة صالحة فقط داخل المصيد
يقدم ES6 الكلمة الرئيسية Let Let لإنشاء نطاق على مستوى الكتلة للمتغيرات التي تعلن عنها. ومع ذلك ، في الوضع الحالي لـ ES3 و ES5 ، غالبًا ما تستخدم عبارات المحاولة لتحقيق تأثيرات مماثلة
من الكود التالي ، يوجد E فقط داخل جملة Catch ، وسيتم إلقاء خطأ عند محاولة الرجوع إليه من مكان آخر.
نسخة الكود كما يلي:
يحاول{
رمي خطأ جديد () ؛ // أعلى خطأ
} catch (e) {
console.log (e) ؛ // error (...)
}
console.log (e) ؛ // uncaughter referenererror: e غير محدد
أخطاء شائعة
جوهر معالجة الأخطاء هو معرفة الأخطاء أولاً في الكود. نظرًا لكتابة JavaScript بشكل فضفاض ولا تتحقق من معلمات الوظيفة ، فلن يحدث الخطأ إلا أثناء الرمز. بشكل عام ، يجب الاهتمام بثلاثة أنواع من الأخطاء: خطأ في تحويل النوع وخطأ نوع البيانات وخطأ الاتصال
【نوع خطأ التحويل】
يحدث خطأ في التحويل عند استخدام عامل تشغيل ، أو استخدام بنية لغة أخرى لأنواع البيانات التي قد تقوم بتحويل القيم تلقائيًا.
بيان التحكم في التدفق عرضة لكتابة أخطاء التحويل. عبارات مثل IF هل ستعمل تلقائيًا على تحويل أي قيمة إلى منطقية قبل تحديد العملية التالية. خاصة إذا كانت البيانات ، إذا تم استخدامها بشكل غير صحيح ، فمن المرجح أن ترتكب أخطاء.
يتم تعيين المتغيرات غير المستخدمة غير المستخدمة تلقائيًا قيمًا غير محددة. يمكن تحويل القيمة غير المحددة إلى قيمة منطقية خاطئة ، وبالتالي فإن العبارة في الوظيفة التالية تنطبق فعليًا فقط على الحالات التي يتم فيها توفير المعلمة الثالثة. المشكلة هي أنه ليس فقط غير محدد ليتم تحويله إلى خطأ ، كما أنه ليس فقط قيم السلسلة التي يمكن تحويلها إلى صواب. على سبيل المثال ، إذا كانت المعلمة الثالثة هي القيمة 0 ، فإن اختبار IF سوف يفشل ، وسيمر اختبار القيمة اللوغاريتمية 1
نسخة الكود كما يلي:
Concat (STR1 ، Str2 ، Str3) {
var result = str1 + str2 ؛
إذا (str3) {// بالتأكيد لا مثل هذا
النتيجة += str3 ؛
}
نتيجة العودة
}
يعد استخدام القيم غير البليان في عبارات التحكم في التدفق مصدرًا شائعًا للغاية للأخطاء. لتجنب مثل هذه الأخطاء ، من الضروري تمرير القيم المنطقية عند مقارنة الظروف. في الواقع ، يمكن لأداء بعض أشكال المقارنة تحقيق ذلك
نسخة الكود كما يلي:
Concat (STR1 ، Str2 ، Str3) {
var result = str1 + str2 ؛
إذا (typeof str3 == 'string') {// أكثر ملاءمة
النتيجة += str3 ؛
}
نتيجة العودة
}
【خطأ نوع البيانات】
تتم كتابة JavaScript بشكل فضفاض ولن تتم مقارنتها للتأكد من أن نوع بياناتهم صحيح حتى يتم استخدام المتغيرات ومعلمات الوظائف. من أجل التأكد من عدم حدوث أخطاء نوع البيانات ، يمكن كتابة رمز اكتشاف نوع البيانات المناسب فقط. من المرجح أن تحدث أخطاء نوع البيانات عند تمرير قيم غير متوقعة لمرض الوظائف
نسخة الكود كما يلي:
// وظائف غير آمنة ، فإن أي قيمة غير عاجلة ستؤدي إلى أخطاء
الوظيفة Reversesort (القيم) {
إذا (القيم) {
القيم. sort () ؛
القيم. Reverse () ؛
}
}
خطأ شائع آخر هو مقارنة المعلمات مع القيم الخالية. إن مقارنة مع NULL فقط يضمن أن القيم المقابلة ليست فارغة وغير محددة. لضمان أن القيمة التي تم تمريرها صالحة ، لا يكفي اكتشاف القيم الفارغة فقط
نسخة الكود كما يلي:
// وظائف غير آمنة ، فإن أي قيمة غير عاجلة ستؤدي إلى أخطاء
الوظيفة Reversesort (القيم) {
إذا (القيم! = خالية) {
القيم. sort () ؛
القيم. Reverse () ؛
}
}
إذا تم تمرير كائن يحتوي على طريقة SORT () (بدلاً من صفيف)
نسخة الكود كما يلي:
// وظائف غير آمنة ، فإن أي قيمة غير عاجلة ستؤدي إلى أخطاء
الوظيفة Reversesort (القيم) {
if (typeof stable.sort == 'function') {
القيم. sort () ؛
القيم. Reverse () ؛
}
}
في حال كنت تعرف بالضبط النوع الذي يجب أن تنقله ، فمن الأفضل استخدام مثيل لاكتشاف نوع البيانات الخاص به
نسخة الكود كما يلي:
// يتم تجاهل القيم الآمنة ، غير المبتذلة
الوظيفة Reversesort (القيم) {
إذا (مثيل القيم من الصفيف) {
القيم. sort () ؛
القيم. Reverse () ؛
}
}
【خطأ في الاتصال】
مع ظهور برمجة Ajax ، أصبح من الشائع لتطبيقات الويب تحميل المعلومات أو الوظائف ديناميكيًا خلال دورة حياتهم. ومع ذلك ، قد يتسبب أي اتصال بين JavaScript والخادم في حدوث خطأ
المشكلة الأكثر شيوعًا هي أن البيانات لا يتم ترميزها باستخدام EncodeUricomponent () قبل إرسالها إلى الخادم
نسخة الكود كما يلي:
//خطأ
http://www.yourdomain.com/؟redir=http://www.sometherdomain.com؟a=b&c=d
// استدعاء EncodeUricomponent () لجميع الأوتار بعد "Redir =" يمكن حل هذه المشكلة
http://www.yourdomain.com/؟redir=http:٪3A٪2F٪2FWWW.SometherDomain.com٪3FA٪3DB٪26C٪3DD