دليل جافا سكريبت الجزء 6: الاستثناءات ، الفواصل المنقوطة ، حرفية النماذج

ستكون المواضيع في هذا الجزء من ترجمة البرنامج التعليمي لجافا سكريبت هي معالجة الاستثناءات ، وميزات الفاصلة المنقوطة التلقائية ، وحرف النماذج.

الجزء الأول: البرنامج الأول وميزات اللغة والمعايير
الجزء الثاني: نمط الكود وهيكل البرنامج
الجزء الثالث: المتغيرات وأنواع البيانات والتعبيرات والكائنات
الجزء 4: الميزات
الجزء الخامس: المصفوفات والحلقات
الجزء السادس: الاستثناءات ، الفاصلة المنقوطة ، حرفية أحرف البدل
الجزء 7: الوضع الصارم ، هذه الكلمة الرئيسية ، والأحداث ، والوحدات ، والحسابات الرياضية
الجزء الثامن: نظرة عامة على ميزات ES6
الجزء التاسع: نظرة عامة على معايير ES7 و ES8 و ES9



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


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

خذ بعين الاعتبار مقتطف الرمز التالي.

let obj = {value: 'message text'} let notObj let fn = (a) => a.value console.log(fn(obj)) //message text console.log('Before') //Before console.log(fn(notObj)) //,    console.log('After') 

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

إليك ما يبدو عندما تقوم بتشغيل هذا الرمز في Node.js.


استثناء TypeError في Node.js

في حالة حدوث شيء من هذا القبيل في كود JS لصفحة الويب ، سيتم إرسال رسالة مماثلة إلى وحدة تحكم المتصفح. إذا حدث هذا في برنامج حقيقي ، على سبيل المثال - في رمز خادم الويب ، فإن هذا السلوك غير مرغوب فيه للغاية. سيكون من الجيد أن يكون لديك آلية تسمح ، دون إيقاف البرنامج ، بالقبض على الخطأ ، ثم اتخاذ تدابير لتصحيحه. توجد مثل هذه الآلية في جافا سكريبت ، وهي ممثلة في بناء try...catch .

حاول البناء ... الصيد


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

 try { // ,     } catch (e) { //  } 

إذا تم تنفيذ التعليمات البرمجية دون أخطاء ، فلن يتم تنفيذ catch (معالج الاستثناء). في حالة حدوث خطأ ، يتم نقل كائن الخطأ هناك ويتم اتخاذ بعض الإجراءات لمكافحة هذا الخطأ.

نطبق هذا البناء في مثالنا ، مع الحماية بمساعدة أقسام خطيرة من البرنامج - تلك التي fn() استدعاء الوظيفة fn() .

 let obj = {value: 'message text'} let notObj let fn = (a) => a.value try {   console.log(fn(obj)) } catch (e) {   console.log(e.message) } console.log('Before') //Before try {   console.log(fn(notObj)) } catch (e) {   console.log(e.message) //Cannot read property 'value' of undefined } console.log('After') //After 

دعونا نلقي نظرة على نتائج تنفيذ هذا الرمز في Node.js.


معالجة الخطأ في Node.js

كما ترى ، إذا قارنت هذا المثال مع المثال السابق ، يتم الآن تنفيذ جميع التعليمات البرمجية ، والمثال الموجود قبل سطر المشكلة ، والمثال الذي يقع بعده. نقوم "بمعالجة" الخطأ بمجرد طباعة قيم خاصية message لكائن الخطأ إلى وحدة التحكم. ما سيتم معالجة الخطأ الذي حدث في التعليمات البرمجية المستخدمة بالفعل يعتمد على الخطأ.

ناقشنا try...catch block أعلاه ، ولكن في الواقع ، يتضمن هذا البناء كتلة أخرى - finally .

block منع أخيرا


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

 try { //  } catch (e) { //  } finally { //  } 

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

try كتل المحاولة المتداخلة


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

 try { //  try {   //   } finally {   // -  } } catch (e) { } 

في هذه الحالة ، إذا حدث استثناء في كتلة try الداخلية ، فستتم معالجته في catch الخارجية.

exception استثناء ذاتي


يمكن طرح الاستثناءات بنفسك باستخدام بيان throw . إليك كيف تبدو.

 throw value 

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

حول الفاصلة المنقوطة


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

ربما يمكننا القول أن مجتمع مطوري JS مقسم ، فيما يتعلق بالفواصل المنقوطة ، إلى معسكرين. في الوقت نفسه ، هناك أيضًا أدلة نمط جافا سكريبت تصف الفواصل المنقوطة الصريحة ، والأدلة التي توصي بالاستغناء عنها.

كل هذا ممكن بسبب حقيقة أن JavaScript لديها نظام للفواصل المنقوطة التلقائية (Automatic Semicolon Insertion، ASI). ومع ذلك ، حقيقة أنه في رمز JS ، في العديد من المواقف ، يمكنك الاستغناء عن هذه الأحرف ، وحقيقة أن الفواصل المنقوطة يتم وضعها تلقائيًا عند إعداد الرمز للتنفيذ ، لا يعني أن المبرمج لا يحتاج إلى معرفة القواعد التي يحدث بها ذلك. الجهل بهذه القواعد يؤدي إلى الأخطاء.

▍ قواعد الفواصل المنقوطة التلقائية


يضيف المحلل اللغوي JavaScript تلقائيًا الفواصل المنقوطة عند تحليل نص البرنامج في الحالات التالية:

  1. عندما يبدأ السطر التالي برمز يقاطع الرمز الحالي (قد يكون رمز أمر معين موجودًا في عدة أسطر).
  2. عندما يبدأ السطر التالي بالحرف } ، الذي يغلق الكتلة الحالية.
  3. عندما يتم الكشف عن نهاية الملف برمز البرنامج.
  4. في السطر مع أمر return .
  5. في السطر مع أمر break .
  6. في الخط مع أمر throw .
  7. في السطر مع الأمر continue .

▍ أمثلة على التعليمات البرمجية التي لا تعمل كما هو متوقع


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

 const hey = 'hey' const you = 'hey' const heyYou = hey + ' ' + you ['h', 'e', 'y'].forEach((letter) => console.log(letter)) 

عند محاولة تنفيذ هذا الرمز ، سيتم Uncaught TypeError: Cannot read property 'forEach' of undefined خطأ Uncaught TypeError: Cannot read property 'forEach' of undefined لنظام Uncaught TypeError: Cannot read property 'forEach' of undefined ، استنادًا إلى القاعدة رقم 1 ، يحاول تفسير الشفرة على النحو التالي.

 const hey = 'hey'; const you = 'hey'; const heyYou = hey + ' ' + you['h', 'e', 'y'].forEach((letter) => console.log(letter)) 

يمكن حل المشكلة بوضع فاصلة منقوطة بعد السطر قبل الأخير من المثال الأول.

هنا قطعة أخرى من التعليمات البرمجية.

 (1 + 2).toString() 

ستكون نتيجة تنفيذها ناتج السلسلة "3" . ولكن ماذا يحدث إذا ظهر شيء مثل هذا في مقتطف الرمز التالي؟

 const a = 1 const b = 2 const c = a + b (a + b).toString() 

في هذه الحالة ، سيظهر خطأ TypeError: b is not a function لأن الرمز أعلاه سيتم تفسيره على النحو التالي.

 const a = 1 const b = 2 const c = a + b(a + b).toString() 

دعونا نلقي نظرة الآن على مثال يستند إلى القاعدة 4.

 (() => { return {   color: 'white' } })() 

قد تعتقد أن IIFE سيعيد كائنًا يحتوي على خاصية color ، ولكنه في الواقع ليس كذلك. بدلاً من ذلك ، سيتم إرجاع الدالة undefined لأن النظام يضيف فاصلة منقوطة بعد الأمر return .

من أجل حل مشكلة مماثلة ، يجب وضع قوس فتح الحرف الحرفي للكائن على نفس السطر مثل أمر return .

 (() => { return {   color: 'white' } })() 

إذا نظرت إلى جزء التعليمات البرمجية التالي ، فقد تعتقد أنه سيعرض 0 في مربع الرسالة.

 1 + 1 -1 + 1 === 0 ? alert(0) : alert(2) 

لكنه يخرج 2 ، لأنه ، وفقا للقاعدة رقم 1 ، يتم تمثيل هذا الرمز على النحو التالي.

 1 + 1 -1 + 1 === 0 ? alert(0) : alert(2) 

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

  • باستخدام أمر return ، قم بترتيب ما يجب أن يعود من الوظيفة على نفس السطر مثل الأمر. وينطبق الشيء نفسه على أوامر break throw continue .
  • انتبه بشكل خاص للحالات التي يبدأ فيها سطر جديد من التعليمات البرمجية بقوس ، حيث يمكن دمج هذا السطر تلقائيًا مع السطر السابق وتقديمه بواسطة النظام كمحاولة لاستدعاء وظيفة أو محاولة للوصول إلى عنصر صفيف.

بشكل عام ، يمكن القول أنه سواء قمت بوضع فاصلة منقوطة بنفسك ، أو تعتمد على موضعها التلقائي ، فاختبر الرمز للتأكد من أنه يعمل كما هو متوقع تمامًا.

علامات الاقتباس وحرف البدل


لنتحدث عن ميزات استخدام علامات الاقتباس في JavaScript. وبالتحديد ، نتحدث عن الأنواع التالية من الاقتباسات المسموح بها في برامج JS:

  • اقتباسات مفردة.
  • اقتباسات مزدوجة.
  • يقتبس مرة أخرى.

بشكل عام ، يمكن اعتبار الاقتباسات الفردية والمزدوجة نفسها.

 const test = 'test' const bike = "bike" 

لا يوجد فرق بينهما عمليا. ربما يكون الاختلاف الملحوظ الوحيد هو أنه في السلاسل المغلقة بين علامتي اقتباس مفردة ، تحتاج إلى الهروب من حرف علامة اقتباس مفردة ، وفي السلاسل المغلقة بين علامتي اقتباس مزدوجتين ، يكون الحرف مزدوجًا.

 const test = 'test' const test = 'te\'st' const test = 'te"st' const test = "te\"st" const test = "te'st" 

في أدلة أنماط مختلفة ، يمكنك العثور على توصية لاستخدام علامات الاقتباس المفردة وتوصية باستخدام علامات الاقتباس المزدوجة. يقول مؤلف هذه المادة أنه في JS-code يسعى جاهداً لاستخدام علامات الاقتباس المفردة حصريًا ، باستخدام علامات الاقتباس المزدوجة فقط في كود HTML.

ظهر Backticks في JavaScript مع إصدار معيار ES6 في عام 2015. إنها ، من بين الميزات الجديدة الأخرى ، تجعل من الممكن وصف سلاسل متعددة الخطوط بسهولة. يمكن أيضًا تحديد هذه السلاسل باستخدام علامات الاقتباس العادية - باستخدام تسلسل الهروب \n . يبدو هذا.

 const multilineString = 'A string\non multiple lines' 

فواصل معكوسة (عادةً ما يكون زر إدخالها موجودًا على يسار مفتاح الرقم 1 على لوحة المفاتيح) بدون \n .

 const multilineString = `A string on multiple lines` 

لكن احتمالات الاقتباسات لا تقتصر على ذلك. لذا ، إذا تم وصف سلسلة باستخدام backquotes ، فمن الممكن استبدال القيم من حساب تعبيرات JS باستخدام البناء ${} .

 const multilineString = `A string on ${1+1} lines` 

تسمى هذه السلاسل الحرفية النموذجية.

تحتوي قوالب النماذج على الميزات التالية:

  • أنها تدعم نص متعدد الأسطر.
  • إنها تجعل من الممكن استيفاء السلاسل ؛ يمكن استخدام التعبيرات المضمنة فيها.
  • تسمح لك بالعمل مع قوالب ذات علامات ، مما يجعل من الممكن إنشاء لغات خاصة بالنطاق (DSL ، لغة خاصة بالنطاق).

لنتحدث عن هذه الميزات.

text نص متعدد


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

 const string = `First               Second` 

استنتاجه سيعطي تقريبا ما يلي.

 First               Second 

أي ، اتضح أنه عندما تم إدخال هذا النص في المحرر ، ربما كان المبرمج يتوقع أن تظهر الكلمتان First Second ، عند الإخراج ، بشكل صارم تحت بعضهما البعض ، ولكن هذا ليس كذلك في الواقع. للتغلب على هذه المشكلة ، يمكنك بدء نص متعدد الأسطر بتغذية سطر ، وبعد إغلاق علامة الاقتباس الخلفية مباشرةً ، اتصل بطريقة trim() ، التي ستزيل المسافة البيضاء في بداية السطر أو نهايته. مثل هذه الشخصيات ، على وجه الخصوص ، تتضمن مسافات وعلامات تبويب. سيتم أيضًا حذف أحرف نهاية السطر.

يبدو هذا.

 const string = ` First Second`.trim() 

▍ الاستيفاء


من خلال الاستيفاء هنا نعني تحويل المتغيرات والتعبيرات إلى سلاسل. يتم ذلك باستخدام البناء ${} .

 const variable = 'test' const string = `something ${ variable }` //something test 

يمكنك إضافة أي شيء إلى كتلة ${} - حتى التعبيرات.

 const string = `something ${1 + 2 + 3}` const string2 = `something ${foo() ? 'x' : 'y' }` 

سيدخل نص something 6 في ثابت string ، إما أن يكون نص something x أو نص something y سيتم كتابته إلى string2 الثابتة 2. يعتمد ذلك على ما إذا كانت الوظيفة foo() تُرجع صواب أم خطأ (يتم استخدام عامل التشغيل الثلاثي هنا ، والذي إذا كان ما قبل علامة الاستفهام صحيحًا ، فسيُرجع ما يأتي بعد علامة الاستفهام ، وإلا فسيُرجع ما يأتي بعد القولون).

platesقوالب ذات علامات


تستخدم القوالب ذات العلامات في العديد من المكتبات الشعبية. من بينها ، Styled Components و Apollo و GraphQL .

ما يخرج من هذه الأنماط يخضع لبعض المنطق المحدد بواسطة الوظيفة. فيما يلي مثال منقح قليلاً في أحد منشوراتنا يوضح كيفية العمل مع سلاسل القوالب ذات العلامات.

 const esth = 8 function helper(strs, ...keys) { const str1 = strs[0] //ES const str2 = strs[1] //is let additionalPart = '' if (keys[0] == 8) { //8   additionalPart = 'awesome' } else {   additionalPart = 'good' } return `${str1}${keys[0]}${str2}${additionalPart}.` } const es = helper`ES ${esth} is ` console.log(es) //ES 8 is awesome. 

هنا ، إذا كان الرقم 8 مكتوبًا في ثابت esth ، esth الخط ES 8 is awesome في es . خلاف ذلك ، سيكون هناك خط آخر. على سبيل المثال ، إذا كانت esth الرقم 6 ، esth ES 6 is good .

تستخدم Styled Components قوالب ذات علامات لتحديد سلاسل CSS.

 const Button = styled.button` font-size: 1.5em; background-color: black; color: white; `; 

في Apollo ، يتم استخدامها لتحديد استعلامات GraphQL.

 const query = gql` query {   ... } ` 

من خلال معرفة كيفية عمل القوالب ذات styled.button ، من السهل فهم أن styled.button و gql من الأمثلة السابقة ليست سوى وظائف.

 function gql(literals, ...expressions) { } 

على سبيل المثال ، تُرجع الدالة gql() سلسلة قد تكون ناتجة عن أي عملية حسابية. إن المعلمة literals لهذه الوظيفة هي مصفوفة تحتوي على محتويات قالب حرفي مقسم إلى أجزاء ، وتحتوي expresions على نتائج تقييم التعبيرات.

دعونا تحليل السطر التالي.

 const string = helper`something ${1 + 2 + 3} ` 

تحصل وظيفة helper على مجموعة literals تحتوي على عنصرين. في الأول سيكون هناك نص بعده مسافة ، وفي الثاني سيكون هناك سطر فارغ - أي ما بين التعبير ${1 + 2 + 3} ونهاية السطر. سيكون هناك عنصر واحد في صفيف espressions - 6 .
هنا مثال أكثر تعقيدًا.

 const string = helper`something another ${'x'} new line ${1 + 2 + 3} test` 

هنا ، في دالة helper ، سيصبح الصفيف التالي هو المعلمة الأولى.

 [ 'something\nanother ', '\nnew line ', '\ntest' ] 

المصفوفة الثانية ستبدو هكذا.

 [ 'x', 6 ] 

الملخص


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

أعزائي القراء! هل تستخدم قدرات القوالب ذات العلامات في JavaScript؟

Source: https://habr.com/ru/post/ar430376/


All Articles