اذهب إلى المحتوى

نور آغا

الأعضاء
  • المساهمات

    9
  • تاريخ الانضمام

  • تاريخ آخر زيارة

آخر الزوار

لوحة آخر الزوار معطلة ولن تظهر للأعضاء

إنجازات نور آغا

عضو مبتدئ

عضو مبتدئ (1/3)

5

السمعة بالموقع

  1. تُحوِّل الدوال والمعاملات، في أغلب الأحيان، القيم التي تصلها إلى النوع الذي يناسبها وهذا ما يسمى «تحويل النوع». تُحوِّل الدالة alert مثلًا أي قيمة إلى سلسلة نصية تلقائيًا لإظهارها، وتُحوِّل والعمليات الرياضية القيم التي تستعملها إلى أعداد. كما توجد العديد من الحالات التي نكون فيها بحاجة لتحويل قيمة بصريح العبارة إلى النوع المطلوب. لاحظ أنَّ هذا الفصل لا يتحدث عن الكائنات. سندرس الأنواع الأساسية أولًا، وبعدها ننتقل إلى الكائنات، ثم سنتعلم طريقة تحويل الكائن في فصل التحويل من كائن إلى أساسي. التحويل إلى سلسلة نصية يحدث التحويل إلى سلسلة نصية عندما نحتاج إلى الشكل النصي لقيمة ما. مثلًا، تُحوِّل الدالة alert(value)‎ القيمة value المُمرَّرة إليها إلى سلسلة نصية لإظهارها. ويمكن أيضًا استدعاء الدالة String(value)‎ لتحويل أي قيمة value إلى سلسلة نصية: let value=true; alert(typeof value); // Boolean value = String(value); // "true" أصبحت الآن سلسلة نصية قيمتها alert(tyoeof value); // string يكون ناتج التحويل إلى سلسلة نصية عادةً واضحًا، فالقيمة المنطقية false تصبح "false"، والقيمة الخالية null تصبح "null" وهكذا. التحويل إلى عدد يحدث التحويل العددي في الدوال والتعابير الرياضية تلقائيًا. كما في حالة تطبيق عملية القسمة / على قيمتين غير عدديتين: alert("6"/"2"); // الناتج: 3، إذ تحول السلاسل النصية إلى أعداد بإمكاننا استخدام الدالة ‎Number(value)‎ لتحويل القيمة value المُمرَّرة إليها بشكل صريح إلى عدد: let str = "123"; alert(typeof str); // string let num = Number(str); // 123 يتحول إلى العدد alert(typeof num); // number يكون التحويل الصريح ضروريًّا عندما نقرأ القيمة من مصدر نصي مثل العنصر text في النموذج <form> ويكون المطلوب إدخال عدد. ويكون ناتج التحويل NaN (اختصارًا للعبارة Not a Number)، إذا كان من غير الممكن تشكيل عدد من السلسلة النصية. إليك مثلًا: let age = Number("an arbitrary string instead of a number"); alert(age); // NaN, فشلت عملية التحويل table { width: 100%; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; } tr:nth-child(even) { background-color: #dddddd; } .task__importance { color: #999; margin-left: 30px; } .task__answer { border: 3px solid #f7f6ea; margin: 20px 0 14px; position: relative; display: block; padding: 25px 30px; } code { background-color: rgb(250, 250, 250); border-radius: 3px; } قواعد التحويل العددي: القيمة ناتج التحويل Undefined NaN null 0 false و true 0 و 1 string (سلسلة نصية) يتم إزالة المسافات الفارغة من البداية والنهاية. إذا كانت السلسلة النصية المتبقية فارغة، تكون النتيجة 0، أو تتم قراءة العدد من السلسلة النصية. والخطأ يعطي النتيجة NaN. أمثلة: alert (Number(" 123 ")); // 123 alert(Number("123z")); // NaN (error reading a number at "z") alert(Number(true)); // 1 alert(Number(false)); //0 لاحظ أنَّ القيمتين null و undefined لهما خرج مختلف هنا: قيمة null تصبح 0، بينما undefined تصبح NaN. جمع السلاسل النصية عبر المعامل + تُحوَّل أغلب العمليات الرياضية القيم إلى أعداد. ولكن هناك استثناء وحيد يحدث عن الجمع عبر المعامل "+" وكون إحدى القيم المطلوب جمعها سلسلة نصية. يجري آنذاك تحويل القيمة الأخرى إلى سلسلة نصية أيضًا ثمَّ تُضاف إلى القيمة الآخرى وتُجمعان معًا في سلسلة نصية واحدة. إليك المثال التالي الذي يوضح ما سبق: alert(1+'2'); // '12' (سلسلة نصية على اليمين) alert('1'+2); // '12' (سلسلة نصية على اليسار) يحدث هذا فقط عندما يكون أحد المعاملات على الأقل سلسلة نصية. أمَّا في الحالات الأخرى، تُحوَّل القيم إلى أعداد. التحويل إلى قيمة منطقية التحويل المنطقي وهو الأسهل من بين جميع عمليات التحويل. يحدث في العمليات المنطقية (لاحقًا سنتعرف على التحقق من الشروط وغيرها من العمليات المماثلة)، ولكن من الممكن تطبيقه أيضًا بشكل صريح عن طريق استدعاء Boolean(value)‎. قاعدة التحويل: القيم التي تكون فارغة، مثل 0، والسلسلة النصية الفارغة، والقيمة undefined، والقيمة NaN تُحوَّل جميعها إلى false. أما ما تبقى، فيُحوَّل إلى القيمة true. مثلًا: alert(Boolean(1)); // true alert(Boolean(0)); // false alert(Boolean("hello")); // true alert(Boolean ("")); // false لاحظ أنَّ السلسلة العددية التي تحتوي على 0 تصبح true. ولكن هناك بعض اللغات البرمجية (مثل PHP) تحول "0" إلى القيمة false. ولكن في لغة JavaScript، تُحوَّل السلسلة النصية الغير فارغة دائمًا إلى القيمة true: alert(Boolean("0"); // true alert(Boolean(" "); // true تحول المسافات (وأي سلسلة نصية غير فارغة) إلى الخلاصة التحويلات الثلاث الأكثر انتشارًا للأنواع هي التحويل إلى سلسلة نصية، أو عدد، أو قيمة منطقية. التحويل إلى سلسلة نصية: يحدث عندما نريد إظهار خرج معين ويمكن تنفيذه عن طريق String(value)‎. ويكون خرج التحويل إلى سلسلة نصية واضحًا بالنسبة للأنواع الأساسية. التحويل إلى عدد: يحدث في العمليات الرياضية ومن الممكن تنفيذه باستخدام Number(value)‎. ويتبع هذا التحويل القواعد التالية: القيمة ناتج التحويل Undefined NaN null 0 false و true 0 و 1 string يتم قراءة السلسلة النصية كما هي، وتجاهل الفراغات من البداية والنهاية. السلسلة النصية الفارغة تصبح 0. وعند وجود خطأ في نتيجة التحويل تكون النتيجة NaN. التحويل إلى قيم منطقية: يحدث في العمليات المنطقية ويمكن تنفيذه باستخدام Boolean(value)‎. ويتبع هذا التحويل القواعد التالية: القيمة ناتج التحويل 0, null, undefined, NaN, "" false القيم الأخرى true معظم هذه القواعد سهلة الفهم والحفظ. ولكن هناك بعض الاستثناءات أو الأخطاء الشائعة مثل: القيمة undefined كعدد هي NaN وليست 0. "0" والسلاسل النصية المحتوي على فراغات فقط مثل " " تُحوَّل إلى القيمة المنطقية true. تذكر أننا لم ندرس الكائنات بعد. سنعود إليها لاحقًا في فصل التحويل من الكائنات إلى الأنواع الأساسية المخصص للكائنات ولكن بعد تعلم المزيد من مبادئ JavaScript. تمارين 1. تحويلات الأنواع الأهمية: 5 ما هي نتيجة التعابير التالية؟ ""+1+0 ""-1+0 true+false 6/"3" "2"*"3" 4+5+"px" "$"+4+5 "4"-2 "4px"-2 7/0 " -9 "+5 " -9 "-5 null+1 undefined+1 فكر جيدًا، ثم اكتب حلك وقارنه مع الإجابة. الحل: الجمع مع سلسلة نصية مثل ‎""+ 1 يحول العدد 1 إلى سلسلة نصية: ‎""+1="1"‎، ثم لدينا "1"+0 التي تنطبق عليها القاعدة نفسها. الطرح - (مثل معظم العمليات الرياضية) يعمل فقط مع القيم العددية، وبالتالي يحول السلسلة النصية الفارغة "" إلى 0. الجمع مع سلسلة نصية يضم العدد 5 إلى السلسلة النصية. تحول عملية الطرح دائمًا القيم إلى أعداد. لذلك يحول القيمة " ‎-9 " إلى ‎-9 ( ويتجاهل الفراغات حولها). تصبح قيمة null هي 0 بعد تحويلها إلى عدد. القيمة الغير معرفة undefined تصبح NaN بعد تحويلها إلى عدد. ""+1+0 ="10" // (1) ""-1+0 = -1 //(2) true+false 6/"3" =2 "2"*"3" = 6 4+5+"px" = "9px" "$"+4+5 = "$45" "4"-2 = 2 "4px"-2 = NaN 7/0 = Infinity " -9 "+5 = " -9 5" //(3) " -9 "-5 = -14 //(4) null+1 = 1 //(5) undefined+1 = NaN //(6) ترجمة -وبتصرف- للفصل Type conversions من كتاب The JavaScript Language انظر أيضًا المقال التالي: المعاملات في JavaScript المقال السابق: أنواع البيانات كامل مقالات دليل تعلم جافاسكربت
  2. يمكن أن يحتوي المتغير على أي نوع من أنواع البيانات في JavaScript. أي من الممكن أن يكون متغير من نوع سلسلة نصية في وقت ما، ثم يتغير محتواه إلى قيمة عددية وهكذا دواليك. // لا يوجد أي خطأ let message = "hello"; message = 123456; تسمى اللغات البرمجية التي تسمح بتغيير نوع القيم المسندة إلى المتغير بلغات برمجة «ديناميكية النوع» (dynamically typed)، ومعنى ذلك أنه توجد أنواع للبيانات ولكن لا يتم ربط المتغير بنوع معين منها. هنالك سبعة أنواع أساسية في لغة JavaScript. سنذكرها الآن بشكل عام، وسنتحدث في الفصول القادمة عن كل نوع منها بالتفصيل. الأعداد let n=123; n=12.345; يمكن تمثيل الأعداد، بما فيها الأعداد الصحيحة (integers) والعشرية (floating point)، في JavaScript عبر النوع number. هنالك العديد من العمليات التي يمكن تنفيذها على المتغيرات العددية، مثل، الضرب *، والقسمة /، والجمع +، والطرح -، وغيرها من العمليات الرياضية. كما أن هناك «قيم عددية خاصة»، بالإضافة إلى الأعداد العادية، والتي تنتمي أيضًا إلى هذا النوع من البيانات مثل: Infinity، و ‎-Infinity، و NaN. وهاك شرحها: Infinity: وتمثل قيمة اللانهاية الرياضية، وهي قيمة خاصة أكبر من أي عدد موجب آخر. ومن الممكن أن نحصل عليها في عدة حالات منها قسمة عدد على الصفر: alert (1/0); // Infinity أو بالإمكان الإشارة إليها بشكل مباشر: alert (Infinity); // Infinity NaN: هذه القيمة ناتجة عن اختصارالعبارة "Not a Number" (ليس عددًا) وتمثل خطأً حسابيًّا، أو حالة عدم تعيين. وهي نتيجة عملية رياضية خاطئة أو غير معروفة. إليك المثال التالي: alert( "not a number"/2 ); // NaN, لا يمكن إجراء مثل عملية القسمة هذه وتتصف القيمة NaN بأنها «لاصقة» (sticky)، أي بمعنى عندما ُتنفَّذ أي عملية على NaN، فالقيمة الناتجة هي NaN أيضًا. alert ("not a number" / 2+5); // NaN لذلك عند وجود القيمة NaN في أي مكان من التعابير الرياضية، فستطغى على كامل النتيحة. وتنتمي القيم العددية الخاصة شكليًا فقط إلى نوع القيم العددية، لأنها في واقع الأمر لا تعبر عن أعداد بمفهومها الشائع. سنتكلم لاحقًا عن التعامل مع الأعداد في فصل (الأعداد). العمليات الرياضية «آمنة» ممارسة الرياضيات آمنة في JavaScript، وبإمكانك القيام بأي عملية حسابية، مثل: القسمة على صفر، والتعامل مع السلاسل الغير عددية كأعداد، وغيرها من العمليات. ثق تمامًا أن السكربت لن ينتهي بخطأ فادح (أو يتوقف عن العمل). أسوأ ما في الأمر أنك ستحصل على النتيجة NaN. السلاسل النصية (النصوص) تمثَّل النصوص (سنطلق عليها «سلاسل نصية» من الآن وصاعدًا) عبر النوع string. يجب أن تُحاط السلسلة النصية في JavaScript بإشارتي تنصيص. let str = "Hello"; let str2 = 'Single quotes are ok too'; let phrase = `can embed ${str}`; يوجد في لغة JavaScript ثلاثة أنواع من إشارات التنصيص وهي: المزدوجة: مثل "Hello". المفردة: مثل 'Hello'. المائلة: مثل Hello (إضافة الإشارة). إشارتي التنصيص المفرد والمزدوج هما عبارة عن إشارات تنصيص تتصف بأنها «بسيطة» ولا يوجد أي فرق بينها في JavaScript. أما إشارة التنصيص المائلة، فهي عبارة عن إشارات تنصيص لها «وظيفة إضافية»، إذ تسمح لك بإضافة متغيرات وتعابير إلى السلسلة النصية بعد إحاطتها بـ ‎${...}‎. فمثلًا: let name = "أحمد"; // تضمين متغير alert (`مرحبًا، ${name}!`); // مرحبًا، أحمد! // تضمين تعبير alert (`the result is ${1+2}`); // النتيجة هي 3 يُحسب التعبير داخل ‎${...}‎ وتصبح نتيجته جزءًا من السلسلة النصية. بإمكاننا وضع أي شيء هناك مثل: المتغير name أو التعبير الرياضي 1 + 2 أو حتى تعابير برمجية أخرى أكثر تعقيدًا. ولكن أبقِ في ذهنك أن هذا مقتصر فقط على إشارات التنصيص المائلة. ولا تستطيع إشارات التنصيص الأخرى القيام بمثل هذا العمل! alert (" the result is ${1+2}" ); // ${1+2} النتيجة هي // فلا تفعل إشارات التنصيص المزدوجة أي شيء إذا كنت تشعر بصعوبة الأمر، لا تقلق. سنتحدث عنه لاحقًا بشكل موسع في فصل السلاسل النصية. المحارف ليس لها نوع مخصص للأسف يوجد في بعض اللغات البرمجية نوعًا خاصًّا من البيانات للمحرف المفرد (character) ويسمى char في لغة C و Java مثلًا. لا يوجد مثل هذا النوع في JavaScript. ويوجد فقط نوع واحد وهو string (سلسلة نصية) الذي من الممكن أن يحتوي على محرف واحد أو أكثر. النوع المنطقي (البولياني) يأخذ النوع boolean إحدى القيمتين: true (صح) أو false (خطأ) وتدعى هاتان القيمتان بالقيم المنطقية. من الشائع استخدام هذا النوع لحفظ البيانات التي لها القيم (نعم / لا): true تعني "نعم، صحيح"، و false تعني "لا، خطأ". إليك المثال التالي: let nameFieldChecked = true; // name نعم، جرى تحديد الحقل let ageFieldChecked = false; // غير محدَّد age لا، الحقل أضف إلى ذلك أن القيم المنطقية تعبِّر عن ناتج عمليات الموازنة: let isGraeter = 4>1; alert(isGreater); // true إذ نتيجة الموازنة محقَّقة أي القيمة الخالية: null لا تنتمي القيمة الخالية null إلى أي نوع من أنواع البيانات المذكورة سابقًا ولكن لها نوع خاص. يملك هذا النوع الخاص قيمة واحدة هي null: let age = null; في لغة JavaScript، لا يعبِّر النوع null عن مرجع لكائن غير موجود أو مؤشر خالي كما في لغات برمجية أخرى. ولكنه عبارة عن قيمة خاصة تمثِّل "لا شيء"، أو "فارغ"، أو "قيمة غير معلومة". فمثلًا، الشيفرة البرمجية السابقة تعدُّ المتغير age غير معلوم أو فارغ لسبب ما. القيمة الغير معرفة: undefined يمكن تمييز نوع آخر أيضًا للبيانات وهو «غير مُعرَّف» الذي يمثله النوع undefined. ويشكل هذا النوع نوعًا خاصًّا قائمًا بنفسه تمامًا مثل النوع null. أما معنى «غير معرّف» أي أنه لم تُسنَد أية قيمة للمتغير بعد: let x; alert (x); // "undefined" تُعرَض القيمة تقنيًا، من الممكن إسناد القيمة undefined لأي متغير: let x=123; x = undefined; alert(x); // "undefined" ولكن لا أنصحك بالقيام بذلك. نستخدم عادةً القيمة null لإسناد القيمة الخالية أو غير المعروفة لمتغير، ونستخدم undefined للتحقق من أن إذا كان للمتغير قيمة أو لا. الكائنات والرموز النوع object (كائن) هو نوعٌ خاصٌّ. تسمى جميع الأنواع السابقة بالأنواع «الأساسية» (primitive) لأن قيمها تحتوي على شيء واحد فقط (سلسلة نصية أو عدد أو أي شيء آخر). ولكن تُستخدَم الكائنات لتخزين مجموعة من البيانات والكيانات (entity) الأكثر تعقيدًا. سنتعامل معها في فصل الكائنات بعد الانتهاء من دراسة الأنواع الأساسية. يستخدم النوع symbol (رمز) لتشكيل معرّف (identifier) مُميَّز للكائنات. يُفضَّل دراسة هذا النوع بعد الانتهاء من الكائنات ولكن ذكره هنا ضروري لاستكمال جميع أنواع البيانات. المعامل typeof يُحدِّد المعامل typeof نوع الشيء المُمرَّر إليه. ويكون مفيدًا عندما تحتاج إلى معالجة القيم بطرق مختلفة حسب نوعها، أو فقط القيام بفحص سريع لنوع البيانات. ويمكن كتابة الصياغة بطريقتين: معامل: typeof x. تابع: typeof(x)‎. بمعنى آخر، من الممكن استخدامه مع أو بدون الأقواس، وتكون النتيجة واحدة. نتيجة استدعاء typeof x هو سلسلة نصية تمثل اسم النوع: typeof undefined // "undefined" typeof 0 // "number" typeof true // "boolean" typeof "foo" // "string" typeof Symbol("id") // "symbol" typeof Math // "object" (1) typeof null // "object" (2) typeof alert // "function" (3) قد تحتاج لتوضيح نتائج الأسطر الثلاث الأخيرة: Math هو كائن مضمّن في JavaScript ويوفر العمليات الرياضية. سنتحدث عنه لاحقًا في فصل الأعداد، وذكرناه هنا فقط كمثال عن نوع الكائن. نتيجة typeof null هي "object" أي كائن. أليس هذا خطأ؟! بالتأكيد. وقد تم الاعتراف بذلك رسميًا، ولكن بقيت هذه النتيجة من أجل المحافظة على التوافقية. القيمة "null" ليست كائنًا بل هي قيمة لنوع منفصل بحد ذاته. لذلك، مرةً أخرى، نؤكد أنّ هذا خطأ من اللغة نفسها. نتيجة typeof alert هي "function" (دالة)، لأن alert هو دالة في لغة JavaScript. سنتحدث لاحقًا عن التوابع في الفصول القادمة وستلاحظ أنه لا يوجد نوع خاص اسمه "function" في لغة JavaScript. تنتمي التوابع إلى نوع الكائنات ولكن لها معاملة خاصة في typeof. شكليًا، هذا خطأ، ولكنه مفيد جدًا عند التطبيق العملي. الخلاصة هناك سبعة أنواع أساسية من أنواع البيانات في JavaScript هي: number: يمثِّل الأعداد بكل أنوعها: الصحيحة والعشرية. string: يمثِّل السلاسل النصية. ويمكن أن تحتوي السلسلة النصية على محرف واحد أو أكثر، ولكن لا يوجد نوع خاص من أجل المحرف الواحد. boolean: يمثِّل القيم المنطقية (صح / خطأ). null: يمثِّل القيم الخاوية. وهو نوع خاص يملك قيمة وحيدة وهي القيمة null. undefined: قيمة غير معرَّفة تكون قيمةً للمتغيرات التي لم تسند قيمة محدَّدة لها بعد. وهو نوع خاص يملك قيمة وحيدة وهي undefined. object: كائن من أجل بنى البيانات الأكثر تعقيدًا. symbol: رمز للمعرفات الخاصة. ويسمح المعامل typeof بمعرفة أنوع القيم المخزنة في المتغيرات: له شكلين: typeof x أو typeof(x)‎. يعيد سلسلة نصية تحوي اسم النوع، مثل "string". من أجل null يعطي القيمة "object" وهذا خطأ في اللغة، فالقيمة الخالية ليست من نوع الكائن. سنركز في الفصل القادم على القيم الأساسية ثم ننتقل إلى الحديث عن الكائنات. .task__importance { color: #999; margin-left: 30px; } .task__answer { border: 3px solid #f7f6ea; margin: 20px 0 14px; position: relative; display: block; padding: 25px 30px; } code { background-color: rgb(250, 250, 250); border-radius: 3px; } تمارين 1. إشارات تنصيص السلاسل النصية الأهمية: 5 ما هو خرج هذا السكربت؟ let name " Ilya"; alert (`hello ${1}`); //? alert (`hello ${"name"}`); //? alert (`hello ${name}`); //? الحل تُضمن الفاصلة العليا الخلفية التعابير الموجودة داخل ‎${…}‎ في السلسلة النصية: let name " Ilya"; // قيمة التعبير هو 1 alert (`hello ${1}`); // hello1 // "name" قيمة التعبير هي السلسلة النصية alert (`hello ${"name"}`); // hello name // name قيمة التعبير هو ما ضُمِّن بالمتغير alert (`hello ${name}`); // hello Ilya ترجمة -وبتصرف- للفصل Data types من كتاب The JavaScript Language انظر أيضًا المقال التالي: التحويل بين الأنواع المقال السابق: المتغيرات كامل مقالات دليل تعلم جافاسكربت
  3. سوف تحتاج، بالتأكيد، في مرحلة ما من عملك على تطوير التطبيقات في لغة JavaScript للتعامل مع المعلومات. فمثلًا، بإمكانك تخيل العمل على التطبيقين التاليين: متجر إلكتروني – يمكن أن تتضمن المعلومات البضائع التي تباع وسلة التسوق. تطبيق محادثة فورية – يمكن أن تتضمن المعلومات، والمستخدمين، والرسائل وغيرها. إن أردنا تخزين هذه المعلومات، نحتاج إلى شيء يُخزِّنها ويحفظها لنا، وهذا ما تمثله المتغيرات تمامًا. فمثل المتغيرات كمثل الأوعية والآنية التي تحفظ وتُخزِّن كل ما يوضع فيها. المتغير المتغير هو «مَخزَن مُسمَى» (named storage) للبيانات، وهذا المخزن يقع في الذاكرة. بإمكانك استخدام المتغيرات لتخزين البضائع، والزوار وغيرها من البيانات. إن أردت إنشاء متغير جديد في لغة JavaScript، استخدم الكلمة المفتاحية let. تنشئ العبارة البرمجية التالية (أو بمعنى آخر تصرّح عن، أو تُعرِّف) متغيرًا جديدًا باسم "message": let message; الآن، نستطيع وضع بعض البيانات فيه باستخدام معامل الإسناد =: let message; message='Hello'; // 'Hello' خزِّن السلسلة النصية بعد تنفيذ هذه الشيفرة، تُحفَظ السلسلة النصية السابقة في منطقة من الذاكرة مرتبطة بهذا المتغير. ويمكننا الوصول إليها باستخدام اسم المتغير: let message mesaage = 'Hello!'; alert(message); // اظهار محتوى المتغير وللاختصار، من الممكن الدمج بين التصريح عن المتغير وإسناد قيمة معينة له في نفس السطر بالشكل التالي: let message = 'Hello!'; // التصريح عن المتغير وإسناد قيمة له alert(message); // Hello! كما من الممكن أيضًا التصريح عن عدة متغيرات في نفس السطر: let user = 'John', age = 25, message = 'Hello'; يبدو هذا أقصر، ولكن لا أنصحك باستخدام هذه الطريقة. استخدم سطرًا مستقلًا لكل متغير لتسهيل قراءة الشيفرة البرمجية. تبدو المتغيرات المتعددة الأسطر (المكتوبة على أسطر منفصلة) أطول قليلًا، ولكنها أسهل عند القراءة: let user = 'John'; let age =25; let message = 'Hello'; يصرِّح بعض المبرمجين عن عدة متغيرات بأسلوب الأسطر المتعددة بالشكل التالي: let user = 'John', age = 25, message = 'Hello'; أو حتى من الممكن استخدام أسلوب «الفاصلة أولًا» (comma-first): let user = 'John' , age = 25 , message = 'Hello'; برمجيًا، جميع هذه الحالات متماثلة وظيفيًّا. لذلك، يعود الأمر لك لتختار الأنسب والأفضل. ملاحظة حول استخدام var بدلًا من let: في السكربتات القديمة، من الممكن أن تلاحظ استخدام الكلمة المفتاحية var بدلًا من let للتصريح عن المتغيرات: var message = 'Hello'; وللكلمة المفتاحية var نفس عمل let تقريبًا. فهي تصرح أيضًا عن المتغيرات ولكنها تختلف عنها قليلًا، ومن الممكن أن تعتبرها، الطريقة «التقليدية» (old-school) للتصريح عن المتغيرات. هناك فروق دقيقة بين let و var، لكنها حاليًا غير مهمة بالنسبة لك. سندرس هذه الفروق بالتفصيل في فصل المتغير القديم. مثال واقعي للمتغيرات إن أردت فهم مبدأ عمل المتغيرات فهمًا جيدًا، فتخيل «صندوقًا»، وعليه لُصاقة باسم مميز. فمثلًا، بإمكانك تخيل المتغير message بصندوق مسمى بالاسم "message"، وداخل هذا الصندوق القيمة "Hello!‎" بإمكانك وضع أي قيمة في الصندوق، كما بإمكانك تغيير هذه القيمة مرارًا وتكرارًا: let message; message = 'Hello!'; message = 'World!'; // value changed alert(message); ولكن لاحظ أنه عندما تتغير القيمة، تُحذَف البيانات السابقة من المتغير. بإمكانك أيضًا التصريح عن متغيرين ونسخ البيانات من أحدهما إلى الآخر. let hello = 'Hello world!'; let message; // message إلى المتغير hello من المتغير 'Hello world' نسخ القيمة message = hello; // يملك المتغيران الآن البيانات نفسها alert(hello); //Hello world! alert(message); // Hello world! اللغات الوظيفية من الأمور التي تجدر ملاحظتها أيضًا أن اللغات البرمجية الوظيفية، مثل Scala أو Erlang، تمنع تغيير قيم المتغيرات بعد إسنادها إليها. أي عندما تخزن القيمة في الصندوق، في مثل تلك اللغات، فإنها تبقى فيه للأبد. وعند الحاجة إلى تخزين بيانات أخرى، تجبرك اللغة على خلق صندوق آخر (التصريح عن متغير جديد)، ولا يمكنك آنذاك إعادة استخدام الصندوق السابق ولا حتى إعادة الصندوق الحالي الذي أنشأته. هل يمكنك تخيل كومة الصناديق التي ستتراكم بعد فترة من الزمن؟! يبدو الأمر غريبًا وصعبًا قليلًا، ولكن فعليًا هذه اللغات قادرة على إجراء تطويرات جادة ومهمة. كما أنَ بعض المجالات تستغل هذه المحدودية وتعتبرها فائدة كما في الحوسبة المتوازية مثلًا. دراسة مثل هذه اللغات جيد لتوسيع مداركك وآفاقك (حتى لو كنت لا تخطط لاستخدامها قريبًا). تسمية المتغيرات هنالك شرطان لأسماء المتغيرات في JavaScript: يجب ألا يحتوي اسم المتغير إلا على حروف، و أرقام، و الرمزين $ و _ فقط. يمنع استخدام رقم في أول حرف من الاسم، أي يجب ألا يبدأ اسم المتغير برقم. أمثلة عن التسمية الصحيحة للمتغيرات: let userName; let test123; عندما يتألف الاسم من عدة كلمات، يستخدم عادةً أسلوب «سنام الجمل» (camelCase). حيث تكتب الكلمات متتالية دون أي فاصل، وتبدأ كل كلمة بحرف كبير: myVeryLongName. الأمر المميز الآخر هو أنه من الممكن استخدام رمز الدولار $ والشرطة التحتية _ في أسماء المتغيرات. وهما عبارة عن رمزين عاديين، كأي حرف آخر، وليس لهما معنًى خاص. أمثلة عن بعض الأسماء المسموحة: let $=1; // "$" التصريح عن متغير اسمه let _=2; // "_" والتصريح عن متغير آخر اسمه alert($ + _); // 3 وأمثلة عن بعض أسماء المتغيرات المكتوبة خطأً: let 1a; // لا يمكن بدء اسم المتغير برقم let my-name; // لا يسمح باستعمال الشرطة '-' في أسماء المتغيرات ملاحظة: حالة الأحرف مهمة فالمتغير الذي اسمه apple مختلفٌ تمامًا عن المتغير الذي اسمه AppLE. ملاحظة: استخدام أحرف من لغات أخرى غير الإنجليزية من الممكن استخدام أحرف من أي لغة غير الإنجليزية وحتى الأحرف العربية أو السيريلية أو الهيروغليفية، ولكن لا ننصحك بذلك. فمثلًا: let имя = '…'; let 我 = '…'; let رسالة = '…'; برمجيًا، لا توجد أية أخطاء هنا، ومثل هذه الأسماء ممكنة، ولكن هناك تقليد عالمي باستخدام أسماء متغيرات إنجليزية. فحتى لو كنت تكتب سكربتًا صغيرًا ولكن من الممكن أن يبقى فترة طويلة ويصل إلى مبرمجين من بلدان أخرى في وقت ما. الأسماء المحجوزة هناك قائمة من الكلمات المحجوزة، والتي ليس ممكنًا استخدامها كأسماء للمتغيرات لأنها مستخدمة من قبل اللغة نفسها. مثلًا، الكلمات التالية: let، و class، و return، و function محجوزة. والشيفرة البرمجية التالية سينتج عنها خطأ في الصياغة: let let = 5; // "let" خطأ! لا يمكن تسمية المتغير بالاسم let return = 5; // أيضًا "return" خطأ! لا يمكن تسمية المتغير بالاسم الإسناد بعيدًا عن الوضع الصارم نحتاج عادةً إلى التصريح عن متغير قبل استخدامه. ولكن سابقًا، كان من المسموح برمجيًا خلق المتغير فقط بإسناد قيمة له دون استخدام let أو أي كلمة مفتاحية أخرى. ما زال هذا ممكنًا، ولكن بشرط عدم استخدام الموجه "use strict" في السكربت وذلك لضمان استمرارية التوافق مع السكربتات السابقة. // هنا "use strict" انتبه إلى عدم استخدام الموجه num = 5; // إن لم يكن موجودًا "num" سيُنشَأ المتغير alert(num); // 5 ولكن أبقِ في ذهنك أنها طريقة سيئة، وسينتج عنها خطأ عند عملك ضمن الوضع الصارم (strict mode): "use strict" num = 5; // error: num is not defined الثوابت للتصريح عن ثابت، وهو المتغير الذي لا تتبدل قيمته، استخدم const بدلًا من let: const myBirthday = '18.04.1982'; المتغيرات التي يُصرَّح عنها باستخدام const تُسمَّى «الثوابت» ولا يمكن أن تتغير قيمتها؛ وأي محاولة للقيام بذلك ينتج عنها خطأ عند تنفيذ الشيفرة: const myBirthday = '18.0401982'; myBirthday = '01.01.2001'; // خطأ! لا يمكن إعادة إسناد قيمة لثابت يستخدم المبرمج الثابت عندما يكون متأكدًا أن قيمة المتغير لن تتبدل أو لا يجب أن تتبدل ضمن البرنامج، ويصرح عنه باستخدام const. أما الفائدة من ذلك فهي ضمان والتحقق من وصول هذه الحقيقة إلى الجميع. متى تستخدم الأحرف الكبيرة في تسمية الثوابت؟ هنالك عرف منتشر في استخدام الثوابت كأسماء مستعارة أو مرادفات للقيم صعبة الحفظ أو القيم العددية الثابتة المعروفة قبل التنفيذ. تسمى مثل هذه الثوابت باستخدام الأحرف الكبيرة والشرطة السفلية (_). كما في هذا المثال: const COLOR_RED = "#F00"; const COLOR_GREEN = '#0F0"; const COLOR_BLUE = '#00F"; const COLOR_ORANGE = '#FF7F00"; // .. عندما نريد انتقاء لون let color = COLOR_ORANGE; alert(color); // #FF7F00 والفائدة من ذلك: حفظ وتَذكُّر COLOR_ORANGE أسهل بكثير من "‎#FF7F00". احتمال ارتكاب خطأ بكتابة "‎#FF7F00" أكبر بكثير من كتابة COLOR_ORANGE. قراءة الاسم COLOR_ORANGE في الشيفرة البرمجية له معنًى جلي خلافًا لقراءة ‎#FF7F00. ربما تتساءل الآن وأنت في حيرة، متى تستخدم الأحرف الكبيرة لتسمية الثوابت ومتى نسميها بالشكل الاعتيادي؟ حسنًا، سنوضح ذلك الآن. عندما تصرِّح عن ثابت، فهذا يعني أن قيمة هذا المتغير لن تتبدل أبدًا. ولكن ميز بين نوعين من الثوابت: الأول هو الثوابت التي تكون قيمتها معروفة قبل التنفيذ (كما في المثال السابق، فالقيمة الست عشرية للون الأحمر معروفة سابقًا وثابتة). أما النوع الثاني، فهو الثوابت التي تحسب قيمتها أثناء عمل السكربت، وخلال التنفيذ، ولكنها لا تتغير بعد إسناد قيمة لها. مثال على ذلك: const pageLoadTime = /* الوقت الذي تستغرقه الصفحة للتحميل */; قيمة الثابت pageLoadTime تكون غير معروفة قبل تحميل الصفحة، لذلك يتم تسمية الثابت بشكل عادي. ولكنه ثابت لأنَّ قيمته لا تتغير بعد إسنادها له. بمعنًى آخر، الثوابت المسماة بأحرف كبيرة تُستخدَم فقط كمرادفات للقيم صعبة الكتابة في الشيفرة البرمجية (hard-coded). تسمية الأشياء تسميةً صحيحةً بما أننا نتكلم عن المتغيرات، لابدّ أن نذكر أمرًا مهمًّا للغاية متعلق بتسمية المتغيرات. أرجوك أن تختار أسماء منطقية للمتغيرات، وأن تأخذ الوقت الكافي للتفكير بالأسماء المناسبة لها. لا تُعدُّ مهمة تسمية المتغيرات مهمةً بسيطةً، فهي واحدة من المهارات الأكثر أهمية وتعقيدًا في البرمجة. و بإمكانك بنظرة سريعة على أسماء المتغيرات المستخدمة في الشيفرة البرمجية معرفة مدى خبرة المطور الذي كتبه. في الواقع، وعند العمل على أي مشروع، فإن أغلب الوقت يمضي في تعديل وتوسيع الشيفرة البرمجية الموجودة بدلًا من كتابة شيفرة برمجية جديدة من الصفر. لذلك، عندما تعود إلى شيفرتك البرمجية بعد القيام بأشياء أخرى لفترة، يكون سهلًا بالنسبة إليك إيجاد المعلومات المسماة بشكل جيد. أو بمعنى آخر، عندما تملك المتغيرات أسماء جيدة. رجائي لك، مرةً أخرى، أن تمضي بعض الوقت في التفكير في الأسماء الصحيحة للمتغيرات قبل التصريح عنها. القيام بذلك سيعود عليك بالنفع بشكل رائع. وإليك بعض النصائح الجيدة لاتباعها في تسمية المتغيرات: استخدم أسماء يمكن للآخرين قرائتها وفهمها مثل userName أو shoppingCart. ابتعد عن الاختصارات أو الأسماء القصيرة مثل a، أو b، أو c إلا إذا كان العمل واضحًا لك بشكل جيد. اجعل أسماء المتغيرات تصف محتواها ولكن لا تبالغ كثيرًا، بل حاول أن تكون مختصرة أيضًا. وكمثال عن الأسماء السيئة data و value. مثل هذه الأسماء لا تعبر عن أي شيء. ومن الممكن استخدامها فقط إذا كان سياق الشيفرة البرمجية، يوضح بشكل بديهي واستثنائي، أي بيانات أو قيم يشير إليها المتغير. اتفق على شروط معينة ضمن فريقك أو حتى مع نفسك في تسمية المتغيرات. فإذا كان اسم زائر الموقع هو user، فإن اسم المتغيرات المرتبطة به تكون أسماؤها currentUser أو newUser عوضًا عن currentVisitor أو NewManInTown. يبدو ذلك بسيطًا، أليس كذلك؟ بالتأكيد، إنها عملية بسيطة. ولكن اختيار أسماء جيدة ومختصرة ليس بالأمر السهل في الحياة العملية، ولكن ننصحك بإيلاء أسماء المتغيرات أهمية كبيرة واختيارها بعناية مطلقة. هل تعيد استخدام المتغير أم تخلق متغيرًا جديدًا؟ أخيرًا وليس آخرًا، هناك بعض المبرمجين الكسالى الذين يفضلون إعادة استخدام المتغيرات الموجودة عوضًا عن خلق متغيرات جديدة. وبالنتيجة، تصبح متغيراتهم مثل الصناديق التي يرمي فيها الناس أشياء مختلفة من دون تغيير مسمياتهم. ماذا يوجد الآن داخل الصندوق؟ لا أحد يعلم. نحتاج إلى الاقتراب والتحقق من محتواه. قد يوفر هؤلاء المبرمجون بعض الوقت لعدم تصريحهم عن متغيرات جديدة. ولكنهم يخسرون عشرة أضعاف هذا الوقت عند استكشاف الأخطاء. المتغير الإضافي هو أمر جيد وليس سيء. وتعمل «مصغرات» (minifiers) لغة JavaScript الحالية والمتصفح على تحسين الشيفرة البرمجية بشكل جيد، وذلك لتفادي أية مشاكل في أدائها. كما أن استخدام المتغيرات المختلفة للقيم المختلفة يساعد المحرك أيضًا في تحسين شيفرتك البرمجية. الخلاصة بإمكاننا التصريح عن المتغيرات لتخزين البيانات باستخدام الكلمات المفتاحية var، أو let، أو const. let: تستخدم للتصريح عن المتغيرات في النسخة الحالية. كما يجب استخدام الوضع الصارم (strict mode) لاستخدام let في V8. var: هي الطريقة التقليدية للتصريح عن المتغيرات. عادةً، لا نستخدم هذه الطريقة على الإطلاق، ولكن سنتعرف على الفروقات الدقيقة بينها وبين let في مقال إفادة var القديمة وهذا أمر ضروري في حال اضطررت لاستخدامها. const: مثل let، ولكن قيمة المتغير لا يمكن تعديلها. كما يجب تسمية المتغيرات بطريقة تسمح لنا بفهم القيم المسندة إليها بسهولة. .task__importance { color: #999; margin-left: 30px; } .task__answer { border: 3px solid #f7f6ea; margin: 20px 0 14px; position: relative; display: block; padding: 25px 30px; } تمارين 1. العمل مع المتغيرات الأهمية: 2 صرّح عن المتغيرين: admin و name. أسند القيمة "John" إلى المتغير name. انسخ قيمة name إلى المتغير admin. اعرض قيمة المتغير admin باستخدام التنبيه alert (يجب أن يكون الخرج "John"). الحل: في الشيفرة البرمجية التالية، كل سطر يمثل أحد الأمور المطلوبة في قائمة المهام: let admin, name; // يمكننا التصريح عن متغيرين في الوقت نفسه name = "Mohammad"; admin= name; alert (admin); // "Mohammad" 2. اختيار الأسماء المناسبة الأهمية: 3 أنشئ متغيرًا وليكن اسمه كوكبنا (our planet). كيف يمكنك تسمية هذا المتغير؟ أنشئ متغيرًا لتخزين اسم الزائر الحالي للموقع. كيف بإمكانك اختيار اسم هذا المتغير؟ الحل: أولًا: المتغير باسم كوكبنا، هذا أمر سهل: let ourPlanetName = "Earth"; لاحظ أنه بالإمكان استخدام اسم أقصر من ذلك مثل planet، ولكن ذلك قد لا يكون واضحًا بالشكل الكافي، أي كوكب نقصد؟ لذلك من الجيد أن تكون أكثر تفصيلًا. على الأقل عندما يكون اسم المتغير ليس طويلًا isNotTooLong. ثانيًا: اسم المتغير الذي يحوي بيانات الزائر الحالي للموقع: let currnetUserName = "John"; مرةً أخرى، بالإمكان اختصار هذا الاسم إلى username، إذا كنت متأكدًا أن هذا الزائر هو الزائر الحالي. المحررات الحالية فيها ميزة الإكمال التلقائي والتي تجعل من السهل كتابة أسماء المتغيرات الطويلة. لا تختصر في اختيار أسماء المتغيرات، فأي اسم يتألف من 3 كلمات هو أمر عادي ومقبول. وإذا كانت ميزة الإكمال التلقائي في محررك سيئة أو غير مناسبة، لا تتردد في تغييره. 3. الثوابت بالأحرف الكبيرة؟ الأهمية: 4 تفحص الشيفرة البرمجية التالية: const birthday = '18.04.1982'; const age = someCode(birthday); هنا لدينا الثابت birthday الذي يحوي تاريخًا والثابت age الذي سيُحسَب من birthday عن طريق الشيفرة البرمجية someCode (لم يتم كتابتها للاختصار، ولأن هذه التفاصيل غير مهمة الآن). هل يكون صحيحًا استخدام الأحرف الكبيرة لتسمية الثابت birthday أو الثابت age أو كلاهما؟ const BIRTHDAY = '18.04.1982'; // هل يُكتَب اسم المتغير بالأحرف الكبيرة؟ const AGE = someCode(BIRTHDAY); // هل يُكتَب اسم المتغير بالأحرف الكبيرة؟ الحل: نستخدم عادةً الأحرف الكبيرة لتسمية الثوابت كمرادفات للقيم صعبة الكتابة في الشيفرة البرمجية (hard-coded). أو بمعنى آخر، عندما تكون قيمة الثابت معروفة قبل التنفيذ ومكتوبة بشكل مباشر في الشيفرة البرمجية. في هذه الشيفرة البرمجية، يمثل الثابت birthday هذه الحالة تمامًا. لذلك نستطيع تسميته بأحرف كبيرة. وبشكل معاكس، فإن الثابت age يُحسَب أثناء عمل السكربت، اليوم يكون لنا عمر معين ولكن يختلف عمرنا في السنة القادمة، هو ثابت من ناحية عدم تغير قيمته أثناء تنفيذ الشيفرة البرمجية ولكنه أقل ثباتًا من الثابت birthday. وبما أننا نقوم بحسابه، لذلك يفضل إبقاء اسمه بالأحرف الصغيرة. ترجمة -وبتصرف- للفصل Variables من كتاب The JavaScript Language انظر أيضًا المقال التالي: أنواع البيانات المقال السابق: الوضع الصارم: النمط الحديث لكتابة الشيفرات كامل مقالات دليل تعلم جافاسكربت
  4. تطورت لغة JavaScript خلال فترة طويلة دون أي مشاكل في التوافق. وجرى التحقق من استمرار عمل جميع وظائفها في كل مرة تضاف إليها خصائص جديدة. وكان لذلك فائدة كبيرة في استمرار عمل الشيفرات البرمجية الموجودة دون تعطلها. ولكن كان له ناحية سلبية أيضًا، هي أنّ الأخطاء والخصائص التي أضافها مطورو اللغة بقيت مع اللغة إلى الأبد. واستمرت هذا الحال حتى ظهور ECMAScript 5 (اختصارًا ES5) في عام 2009. التي أضافت خصائص جديدة إلى اللغة وعدّلت على بعض الخصائص الموجودة سابقًا. ولضمان استمرار عمل الشيفرات البرمجية السابقة، فإنّ معظم هذه التعديلات كانت غير فعّالة بشكل افتراضي؛ ولاستخدامها، عليك تفعيلها بشكل صريح باستخدام الموجه الخاص: "use strict". الموجه "use strict" يبدو الموجه كسلسلة نصية: "use-strict" أو 'use strict'. وعندما يوضع في بداية السكربت، يُنفَّذ السكربت وفق الطريقة والمعايير الحديثة. إليك المثال التالي: "use strict"; //هذه الشيفرة البرمجية تعمل في الوضع الصارم … قريبًا، سندرس الدوال (طريقة لجمع الأوامر). ولكن في نطرة استباقية للموضوع، لاحظ أنه بالإمكان وضع "use strict" في بداية معظم أنواع الدوال عوضًا عن كامل السكربت. وبذلك يتم تفعيل الوضع الصارم (strict mode) ضمن الدوال فقط. لكن عادةً يستخدم المبرمجون هذا الوضع لكامل السكربت. تأكد من وضع "use script" في بداية السكربتات، وإلا فإنه من الممكن ألا يُفعَّل الوضع الصارم. فمثلًا، الوضع الصارم غير مفعّل في المثال التالي: alert("some code"); // إن لم يُستعمَل في أول سطر "use strict" سيجري تجاهل الموجه "use strict" // الوضع الصارم غير مُفعَّل بإمكانك كتابة التعليقات فقط قبل استخدام الموجه "use strict". لاحظ أيضًا أنه ليس هناك طريقة لإلغاء "use strict"، أي لا يوجد موجه آخر مثل "no use strict" والذي يثني المحرك عن عمله ويلغي تفعيل الوضع الصارم. لذلك عند بدء استخدام الوضع الصارم، لا توجد طريقة لإلغائه والعودة إلى الوضع الافتراضي. طرفية المتصفح أبقِ في ذهنك أن طرفية المتصفح (console) لا تستخدم الوضع الصارم لاختبار وتنفيذ الشيفرات المكتوبة فيها؛ أي أنها لا تستخدم "use strict" افتراضيًا. عندما يوجد هناك اختلاف بين "use strict" والنمط الافتراضي في بعض الأحيان، قد تحصل على ناتج خطأ. ولن تنجح محاولتك في تفعيل الوضع الصارم (strict) بالضغط على الاختصار Shift+Enter لإدخال عدة أسطر، ثم استخدام "use strict" في البداية وذلك بسبب طريقة معالجة الطرفية للشيفرة البرمجية داخليًا. الطريقة الأفضل للتأكد من عمل "use strict" هو كتابة الشيفرة البرمجية ضمن الطرفية كما يلي: (function() { 'use strict'; // … ضع شيفرتك هنا … })() استخدم "use strict" دومًا سنتعلم لاحقًا الاختلافات بين الوضع الصارم والوضع الافتراضي الذي تعمل ضمنه الشيفرات. ففي الفصل القادم، ستلاحظ الاختلافات بين هذين الوضعين أثناء تعلمك للخصائص الجديدة. من الجيد أنه لا يوجد الكثير من هذه الاختلافات، وفي حال وجودها فهي لتحسين عمل الشيفرة البرمجية. ولكن في الوقت الحالي تكفي معرفتك بهذه الأمور العامة: الموجه "use strict" يحول المحرك إلى النمط الحديث (modern)، مما يغير من طريقة تعامله مع بعض الخصائص الموجودة سابقًا. سندرس ذلك بالتفصيل في الأجزاء القادمة من هذه السلسلة التعليمية. يتم تفعيل الوضع الصارم بوضع الموجه "use strict" في بداية السكربت أو الدالة. العديد من خصائص اللغة، مثل الأصناف (classes) والوحدات (modules)، ُتفعِّل الوضع الصارم (strict) تلقائيًا. الوضع الصارم (strict) مدعوم من قبل جميع المتصفحات الحالية. أنصحك دائمًا بوضع "use strict" في بداية السكربت. جميع الأمثلة في هذه السلسلة التعليمية تفترض العمل ضمن الوضع الصارم إلا إذا ذُكر غير ذلك وهذا في بعض الحالات النادرة. ترجمة -وبتصرف- للفصل "Modern mode, "use strict من كتاب The JavaScript Language انظر أيضًا المقال التالي: المتغيرات المقال السابق: بنية الشيفرة البرمجية كامل مقالات دليل تعلم جافاسكربت
  5. في هذا المقال، سنبدأ بتعلم أساسيات كتابة الشيفرة البرمجية في لغة JavaScript. هل أنت مستعد؟ لننطلق! التعابير البرمجية التعابير البرمجية هي صياغة التراكيب والأوامر التي تنفذ الأعمال في السكربت. رأيت سابقًا التعبير البرمجي alert('Hello, world!')‎ الذي يُظهر الرسالة "Hello, world!‎". بإمكانك استخدام تعابير بقدر ما تريد في شيفرتك البرمجية. ويمكن فصل التعابير البرمجية عن بعضها بالفاصلة المنقوطة (;). مثلًا، بإمكاننا فصل "Hello World" إلى تنبيهين منفصلين بالشكل التالي: alert('Hello'); alert('World'); تُكتَب التعابير البرمجية عادةً على أسطر منفصلة لتسهيل قراءة الشيفرة البرمجية: alert('Hello'); alert('World'); الفاصلة المنقوطة يمكن حذف الفاصلة المنقوطة من آخر التعابير البرمجية في معظم الحالات عند الانتقال إلى سطر جديد. أي أن الشيفرة البرمجية التالية ستعمل أيضًا بشكل صحيح: alert('Hello') alert('World') تُفسِّر لغة JavaScript الانتقال إلى سطر جديد بفاصلة منقوطة (ضمنيًا). وهذا ما يُسمى (الاضافة التلقائية للفاصلة المنقوطة [Automatic semicolon insertion]). في معظم الحالات، يتضمن السطر جديد فاصلةً منقوطةً افتراضية في آخره ولكن هذا لا يشمل جميع الحالات. هناك حالات لا يحوي فيها السطر الجديد بالضرورة فاصلةً منقوطةً افتراضية. إليك مثلًا: alert(3+ 1 +2); خرج الشيفرة البرمجية السابقة هو 6 لأنَّ لغة JavaScript لا تضيف الفاصلة المنقوطة في هذه الحالة. فمن البديهي أنه عند انتهاء السطر بإشارة "+" يكون التعبير ناقصًا (incomplete expression)، وبالتالي لا يتطلب وجود فاصلة منقوطة. لذلك، تعمل الشيفرة البرمجية كما هو مطلوب. لا تعتمد دائمًا على JavaScript لإضافة الفاصلة المنقوطة لأنه توجد حالات تفشل فيها لغة JavaScript بإضافة الفاصلة المنقوطة عندما تكون مطلوبة. والأخطاء التي تحدث نتيجة هذه الحالات صعبة الإيجاد والإصلاح (ستكتشف ذلك قريبًا خلال الشيفرات التي ستكتبها). إذا كنت ترغب في الاطلاع على مثال واقعي عن هذه الحالة، إليك الشيفرة البرمجية التالية: [1, 2].foreach(alert) لا تقلق إن كانت هذه الشيفرة صعبة الفهم عليك، فليس هناك حاجة الآن لفهم معنى الأقواس المعقوفة [] أو التعبير البرمجي forEach، فسندرسهم لاحقًا. ولكن أبقِ في ذهنك أن خرج هذه الشيفرة البرمجية هو إظهار 1 ثم 2. سنضيف الآن تنبيهًا (alert) قبل الشيفرة البرمجية السابقة دون وضع الفاصلة المنقوطة في نهاية العبارة البرمجية: alert("There will be an error") [1 ,2].forEach(alert) عند تنفيذ الشيفرة البرمجية آنذاك، سيتم إظهار التنبيه الأول فقط ثم سنحصل على خطأ. تعود الشيفرة البرمجية للعمل بشكل صحيح مرة أخرى عند إضافة الفاصلة المنقوطة بعد التنبيه الأول: alert("All fine now"); [1 ,2].forEach(alert) تظهر لدينا الآن الرسالة "All fine now"، ثم 1 و 2. الخطأ الذي حدث في الحالة الأولى (حالة عدم إضافة الفاصلة المنقوطة) سببه أنَّ لغة JavaScript لا تضيف الفاصلة المنقوطة تلقائيًا عند الانتقال إلى سطر جديد في حال وجود الأقواس المعقوفة […] في بداية هذا السطر. وبالتالي لن تُضاف الفاصلة المنقوطة تلقائيًا في الحالة الأولى وسيتم التعامل مع الشيفرة البرمجية كعبارة برمجية واحدة. أي سيراها المحرك بالشكل التالي: alert("There will be an error")[1, 2].forEach(alert) ولكنهما عبارتين برمجيتين منفصلتين وليستا عبارة واحدة، وبالتالي عملية الدمج في هذه الحالة خطأ. من الممكن أن تتكرر هذه الحالة ضمن شروط أخرى. بناءً على ما سبق، ننصحك بإضافة الفاصلة المنقوطة بين التعابير البرمجيَّة حتى لو قمت بفصلها بأسطر جديدة. وهذه هي القاعدة الأكثر اتباعًا بين مستخدمي JavaScript. لنراجع سويةً ما ذُكر سابقًا، من الممكن الاستغناء عن الفاصلة المنقوطة في معظم الحالات، ولكن من الأفضل إضافتها في آخر العبارة البرمجية - وخاصةً بالنسبة للمبتدئين - تجنبًا للوقوع في أخطاء عصية التنقيح والتصحيح أنت بغنًى عنها. التعليقات تصبح البرامج أكثر تعقيدًا مع مرور الوقت. ويكون ضروريًا إضافة التعليقات لشرح عمل الشيفرة البرمجية. يمكن وضع التعليقات في أي مكان ضمن السكربت دون أن تؤثر على تنفيذه، لأنَّ المحرك ببساطة يتجاهل جميع التعليقات. التعليقات المكتوبة على سطر واحد تبدأ بخطين مائلين (forward slash) بالشكل //. ويكون الجزء التالي للخطين المائلين على نفس السطر تعليقًا. ومن الممكن أن يشغل التعليق سطرًا كاملًا أو يأتي التعليق بعد العبارة البرمجية. إليك المثال التالي الذي يشرح ما سبق: // يمتد هذا التعليق على كامل السطر فقط alert('Hello'); alert('World'); // هذا تعليق يلي تعبيرًا برمجيًّا وإن أردت كتابة تعليقات تمتد على عدَّة أسطر، فابدأ التعليق متعدد الأسطر بخط مائل يليه رمز النجمة (أي ‎/*‎) ، وأنهِ التعليق برمز النجمة ثم الخط المائل (أي ‎*/‎) . إليك المثال التالي: /* يُظهر هذا المثال تنبيهين وهذا التعليق متعدد الأسطر */ alert('Hello'); alert('World'); يجري تجاهل كل ما يقع داخل التعليق متعدد الأسطر، وبالتالي لا تُنفَّذ أية شيفرة برمجية موجودة داخل /*…*/. أحيانًا، يكون من المفيد إلغاء تفعيل جزء من الشيفرة البرمجية مؤقتًا أثناء تنقيح الأخطاء: /* تعليق جزء من الشيفرة alert('Hello'); */ alert('World'); استخدام الاختصارات من الممكن تعليق سطر واحد من الشيفرة البرمجية بالضغط على الاختصار Ctrl+/‎ في معظم المُحرِّرات وبيئات التطوير. ومن أجل التعليقات متعددة الأسطر من الممكن استخدام الاختصار Ctrl+Shift+/، (عليك أن تحدد جزءًا من الشيفرة البرمجية ثم الضغط على الاختصار). في الأجهزة التي تعمل على الماك، جرّب Cmd عوضًا عن Ctrl. تحذير: التعليقات المتداخلة متعددة الأسطر غير مدعومة. أي لا يمكنك وضع /*…*/ داخل /*…*/ آخر، إذ ستنتهي هذه الشيفرة البرمجية بخطأ: /* التعليق الخارجي /*تعليق متشعب*/ لاحظ لوني الأسود */ alert('World'); لا تتردد أبدًا في وضع التعليقات ضمن شيفرتك البرمجية وشرح ما الذي يجري فيها لأنك عندما تعود إليها لاحقًا، ستجد غالبًا أنك نسيت وظيفة كل جزء من شيفرتك. قد تزيد التعليقات من حجم الشيفرة ولكن هذه ليست بمشكلة. هناك العديد من الأدوات التي تُقلِّص الشيفرة البرمجية قبل نشرها على خادم الإنتاج، إذ تَحذِف التعليقات من السكربت نهائيًّا ولا يبقَ لها بذلك أي أثر. في تلك الحالة، لا يكون للتعليقات أي آثار سلبية عند الإنتاج. لا تقلق مرة أخرى إن لم تتضح لك الصورة ولم تفهم بعض المصطلحات (مثل ما الذي يقصد بالإنتاج) فكل شيء سيتضح تدريجيًّا. لاحقًا في هذه السلسلة التعليمية، سيكون هناك فصل عن جودة الشيفرة البرمجية والذي يشرح طريقة كتابة التعليقات بشكل أفضل. ترجمة -وبتصرف- للفصل Code structure من كتاب The JavaScript Language انظر أيضًا المقال التالي: الوضع الصارم: النمط الحديث لكتابة الشيفرات المقال السابق: المثال الأول: أهلًا بالعالم! كامل مقالات دليل تعلم جافاسكربت
  6. أبقِ في ذهنك أنَ هذه السلسلة التعليمية هي عن أساس لغة جافاسكربت (core JavaScript) المستقلة عن أي منصة. سنتعرف لاحقًا على Node.JS والمنصات التي تستخدمها. الآن، نحن بحاجة إلى بيئة للعمل وتشغيل السكربتات التي سنكتبها، ويبدو المتصفح خيارًا جيدًا بما أنك تتابع هذه السلسلة التعليمية عبر الإنترنت. سنقلل من استعمال التعليمات التي تعمل فقط على المتصفح (مثل alert) لكي لا يضيع مجهودك بالتركيز عليها خاصةً إن كنت تنوي العمل في بيئة أخرى (مثل Node.JS). وسنركِّز على لغة JavaScript ضمن المتصفح في الجزء القادم من هذه السلسلة التعليمية. في البداية، سنتعرَّف على طريقة إضافة السكربت إلى صفحة الويب. من أجل البيئات التي تعمل على الخادم (مثل Node.JS)، بإمكانك تنفيذ السكربت عن طريق أمرٍ مثل node my.js. الوسم <script> من الممكن تضمين برامج لغة JavaScript في أي جزء من مستند HTML باستخدام الوسم <script>. على سبيل المثال: <!DOCTYPE HTML> <html> <body> <p>Before the script… </p> <script> alert(‘Hello, world!’); </script> <p>...After the script.</p> </body> </html> يحتوي الوسم <script> على شيفرة JavaScript تُنفَّذ تلقائيًا عندما يعالج المتصفح الوسم. الترميز الحالي يملك الوسم <script> عددًا من الخاصيات، ونادرًا ما يتم استخدامها الآن، ولكن ما زال بإمكانك رؤيتها في الشيفرات البرمجية القديمة. الخاصية type <script type=...> تتطلب معايير لغة HTML القديمة، HTML4، إسناد قيمة للخاصية type في الوسم <script>، وعادةً ما تكون type="text/javascript"‎، لكن هذا الأمر لم يعد ضروريًا. كما أنَ معنى هذه الخاصية تغيَر بشكل كامل وفق معايير لغة HTML بنسختها الحالية، HTML5. وأصبحت تستخدم مع وحدات (modules) لغة JavaScript. ولكنه موضوع متقدم سنتحدث عنه لاحقًا في جزء آخر من هذه السلسلة التعليمية. الخاصية language <script language=...> تُستخدَم هذه الخاصية لتحديد اللغة المكتوب بها السكربت، ولكنها لم تعد مهمة الآن، لأن لغة JavaScript أصبحت هي اللغة الافتراضية، ولم تعد هناك حاجة لاستخدام هذه الخاصيَّة. التعليقات قبل وبعد السكربتات من الممكن أن تجد تعليقات ضمن الوسم <script> في كتب ومراجع لغة JavaScript القديمة، مثل: <script type=”text/javascript”><!-- … //--></script> تعمل هذه التعليقات على إخفاء الشيفرة البرمجية عن المتصفحات القديمة والتي لا تعرف معالجة الوسم <script> ولم تعد مستخدمة في لغة JavaScript بنسختها الحالية. وبما أن نسخ المتصفحات في السنوات الخمسة عشر الماضية لا تملك هذه المشكلة، فإنً هذا النوع من التعليقات يمكًنك من تحديد الشيفرات البرمجية القديمة للغة JavaScript. ما هو الاستعمال الحديث للعنصر <script>؟ عندما تكون الشيفرة البرمجية للغة JavaScript طويلة، قد ترغب في وضعها في ملف مستقل. ويتم ربط ملف السكربت إلى HTML عن طريق الخاصية src: <script src=”/path/to/script.js”></script> هنا المسار path/to/script.js/ هو المسار الكامل لملف السكربت (ابتداءً من جذر الموقع). بإمكانك أيضًا إدخال المسار نسبةً للصفحة الحالية. مثلًا، المسار ("src="script.js) معناه أنً الملف script.js موجود في نفس المجلد الذي توجد فيه الصفحة. بالإمكان أيضًا استخدام عنوان الموقع كاملًا، كما في المثال التالي: <script src=”https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js”></script> وإن أردت ربط عدة سكربتات مع نفس الصفحة، فاستخدم الوسم <script> لكل سكربت على حدة: <script src=”/js/script1.js”></script> <script src=”/js/script2.js”></script> ملاحظة: يمكنك العمل بالقاعدة التالية، «السكربتات البسيطة فقط تُضمَّن مع HTML والسكربتات الأكثر تعقيدًا تُكتَب في ملفات مستقلة». والفائدة من وجود ملف مستقل هي امكانية تنزيل المتصفح لهذا السكربت مرة واحدة وتخزينه في ذاكرة مؤقتة (cache). وبذلك، تتمكن الصفحات الأخرى المرتبطة بنفس السكربت من طلبه وجلبه من الذاكرة المؤقتة عوضًا عن تنزيله مرةً أخرى. وبذلك يتم فعليًا تنزيله مرة واحدة، مما يقلل حركة البيانات عبر الإنترنت ويُسرِّع تحميل ومعالجة صفحات الويب. تحذير: انتبه إلى أنه يجري تجاهل السكربت المكتوب ضمن الوسم <script> في حال ربطه مع ملف مستقل أي عند إسناد قيمة أو مسار معين للخاصية src. بعبارة أخرى، ليس بإمكان الوسم <script> أن يُنفِّذ شيفرتين برمجيَّتين في آن واحد: شيفرة قادمة من الخاصية src وشيفرة برمجية مكتوبة بداخله. فمثلًا، لن تُنفَّذ التعليمة البرمجية alert(1)‎ المكتوبة ضمن الوسم في هذا المثال: <script src=”file.js”> alert(1); // src سيجري تجاهل أي محتوى مكتوب ضمن الوسم بسبب ضبط الخاصية </script> يجب أن تختار أحد الأمرين: ملف خارجي مستقل للسكربت <script src="..."‎>، أو وسم <script> عادي يحوي ضمنه على الشيفرة البرمجية المراد تنفيذها. بالإمكان فصل السكربت في المثال السابق إلى وسمين <script> منفصلين ليعمل بشكل صحيح: <script src=”file.js”></script> <script> alert(1); </script> الخلاصة نستخدم الوسم <script> لتضمين الشيفرة البرمجية للغة JavaScript في صفحة الويب. في الوقت الحالي، لم نعد نستعمل الخاصيتين type و language. يمكن ربط السكربت الموجود في ملف خارجي باستخدام الخاصية src. هنالك الكثير لتعلمه عن السكربتات الممكن تنفيذها في المتصفح وتأثيرها على صفحات الويب. ولكن أبقِ في ذهنك أن هذا الجزء من السلسلة التعليمية يُركِّز على لغة JavaScript ويجب ألا نشوش أنفسنها بالتركيز على معايير تنفيذ السكربتات ضمن كل متصفح بشكل خاص. سنستخدم المتصفح وسيلةً لتنفيذ سكربتات JavaScript لأنه مناسب في حالتنا للتعلم عن طريق الإنترنت، ولكنه إحدى الطرق الكثيرة لتشغيل JavaScript. تمارين 1. إظهار تنبيه .task__importance { color: #999; margin-left: 30px; } .task__answer { border: 3px solid #f7f6ea; margin: 20px 0 14px; position: relative; display: block; padding: 25px 30px; } الأهمية: 5 أنشئ صفحةً تُظهِر الرسالة "I`m JavaScript". بإمكانك تنفيذها في صفحة تجريبية (sandbox)، أو على قرصك الصلب. لا يهم ولكن تأكد من أنها تعمل بالشكل الصحيح. بعد كتابة شيفرتك، نفِّذها ثم تأكد من الإجابة المرفقة. الحل: عرض توضيحي فتح الحل في بيئة تجريبية حية 2. إظهار تنبيه باستخدام سكربت خارجي الأهمية: 5 استخدم الحل في التمرين السابق (إظهار تنبيه)، وعدله لاستخراج الشيفرة البرمجية المراد تنفيذها إلى سكربت خارجي باسم "alert.js" موجود في نفس المجلد. افتح الصفحة وتأكد من عمل التنبيه. الحل: الشيفرة البرمجية لمستند HTML: <!DOCTYPE html> <html> <body> <script src="alert.js"></script> </body> </html> ويحتوي الملف alert.js في نفس المجلد على الشيفرة البرمجية التالية: alert("I'm JavaScript!"); ترجمة -وبتصرف- للفصل !Hello, world من كتاب The JavaScript Language انظر أيضًا المقال التالي: بنية الشيفرة البرمجية المقال السابق: محررات الشيفرة البرمجية كامل مقالات دليل تعلم جافاسكربت
  7. يقضي المبرمجون معظم وقتهم في العمل على أحد محررات الشيفرة البرمجية لكتابة وتطوير برامجهم. سنساعدك في هذا المقال على اختيار المحرر الأنسب لك. بدايةً، يوجد نوعان رئيسيان لمحررات الشيفرة البرمجية: «بيئات التطوير المتكاملة» (Integrated Development Environments وتدعى اختصارًا IDE) و «المحررات البسيطة» (lightweight editors). يستخدم العديد من المبرمجين محرِّرًا واحدًا من كل نوع. في بداية تعلمك للبرمجة، يمكنك استعمال المحررات البسيطة مثل المفكرة (notepad) في ويندوز والمحرر vim أو kate في لينكس ولكن ستحتاج مع تقدمك وتطور وكبر شيفرتك إلى بيئة تطوير متكاملة. فما هي بيئة التطوير المتكاملة؟ بيئة التطوير المتكاملة بيئة التطوير المتكاملة «IDE» عبارة عن محرر شيفرة برمجية قوي، ومزود بمزايا كثيرة ومتنوعة تكفي للعمل عادةً على كامل المشروع. وكما هو واضح من اسمها، فهي ليست كأي محرر عادي، ولكن «بيئة تطوير» شاملة. يمكنك تحميل المشروع بجميع ملفاته إلى بيئة التطوير (IDE)، مما يسمح بالتنقل بينها بسهولة، كما توفر هذه البيئة (IDE) ميزة الإكمال التلقائي أثناء كتابتك للشيفرة البرمجية كالتعليمات وأسماء المتغيرات بالنسبة لكامل المشروع (وليس ضمن الملف المفتوح فقط). وتتيح الاندماج مع نظام التحكم في النسخ مثل git، وبيئة الاختبار، وغيرها من الأمور التي تُنفذ على مستوى المشروع. بإمكانك الاطلاع على خيارات بيئات التطوير (IDE) التالية، لمساعدتك على اختيار واحدة منها للعمل عليها إن لم تحدد واحدة بعد: WebStorm: تستخدم لتطوير الواجهات الأمامية (Front-end development). توفر الشركة محررات أخرى للعديد من اللغات البرمجية ولكنها مدفوعة. NetBeans: بيئة متكاملة ومجانية وتعمل على مختلف أنظمة التشغيل. Visual Studio: خاص بنظام التشغيل «ويندوز»، (ميّز بينه وبين "Visual Studio Code"). وهو محرر قوي ومدفوع، ومناسب جدًا للعمل على منصة «NET.»، ويوجد نسخة مجانية منه تُسمى Visual Studio Community. أغلب بيئات التطوير المتكاملة متعددة المنصات، وتعمل على أنظمة تشغيل مختلفة ولكنها مدفوعة (لها فترة تجريبية مجانية)، وكلفتها متواضعة بالنسبة لدخل المطور المؤهل، لذلك ننصحك باختيار الأفضل والأنسب لك، دون القلق من كلفتها. المحررات البسيطة المحررات البسيطة (Lightweight editors) ليست قوية مثل بيئات التطوير المتكاملة، لكنها سريعة، وأنيقة، وبسيطة الاستخدام. تُستخدَم بشكل أساسي لفتح وتعديل الملف بطريقة سريعة وآنية. الاختلاف الرئيسي بين المحرر البسيط وبيئة التطوير المتكاملة، هو أنّ بيئة التطوير المتكاملة تعمل على «مستوى المشروع»، لذلك تُحمِّل الكثير من البيانات في البداية، وتكون قادرة على تحليل بنية المشروع عند الحاجة وغيرها من المهام. أمّا المحرر البسيط، يكون أسرع بشكل كبير عند الحاجة للعمل على ملف واحد فقط من المشروع. عمليًا، يمكن أن تملك المحررات البسيطة العديد من الإضافات التي تتضمن محللات ومدققات الصياغة على مستوى المشروع وميزة الإكمال التلقائي، وبالتالي لا توجد هناك حدود واضحة بين المحرر الخفيف وبيئة التطوير المتكاملة. لذلك وقبل أن تحسم رأيك باستخدام بيئة تطوير متكاملة، ننصحك بالاطلاع على الخيارات التالية للمحررات البسيطة: Visual Studio Code: مجاني ومتعدد المنصات ويملك العديد من المزايا المشابهة لمزايا بيئة التطوير المتكاملة. Atom: مجاني الاستخدام ومتعدد المنصات. Sublime Text: برنامج تجريبي ومتعدد المنصات ويدعم العديد من اللغات البرمجية (programming languages) واللغات التوصيفية (markup languages). Brackets: محرِّر مجاني ومفتوح المصدر وعابر للمنصات ومخصَّص بشكل عام لمطوري الويب وبشكل خاص لمصممي الويب ومطوري الواجهات الأمامية. ++Notepad: محرِّر مجاني وخاص بنظام التشغيل ويندوز. Vim و Emacs: محِّرران بسيطان، ويعدَّان خيارًا جيدًا إذا كنت تعرف كيفية استخدامهما. ما هو محرري المفضل الذي سأستخدمه؟ نصيحة مني لك هو تجريب الخيارين السابقين كلاهما؛ استخدم بيئة التطوير المتكاملة عند العمل على كامل المشروع، وأحد المحررات الخفيفة من أجل التعديلات السريعة والطفيفة في ملفات المشروع. يمكن في البداية استعمال المحررات الخفيفة (مثل VS code) التي تفي بالغرض في أغلب المشاريع ثمَّ الانتقال إلى البيئات المتكاملة (سواءً المجانية أو المدفوعة) في المستويات المتقدمة عندما تتولد الحاجة إليها. أسمعك تسألني ما الذي استخدمه؟ حسنًا، أنا استخدم: استعمل WebStorm - بيئة التطوير المتكاملة - عند العمل بلغة JavaScript، واستعمل خيارًا آخر من JetBrains مثل IntelliJ IDEA عند العمل بلغات برمجية مختلفة. واستخدم Sublime أو Atom كمحرر خفيف. قبل أن تختلف معي بشأن القائمة السابقة، فإن هذه المحررات هي إما محررات استخدمتها بنفسي أو استخدمها أحد أصدقائي من المطورين الجيدين لوقت طويل وكانوا سعداء باستخدامهم لها. هناك العديد من المحررات الجيدة أيضًا في عالمنا الكبير. لذلك، ننصحك بالعمل على المحرر المفضل لديك. فاختيار المحرر، مثل أي أداة أخرى، هو قرار خاص، ومعتمد على مشروعك، وعاداتك، وتفضيلاتك الشخصية. ولكي تعرف ما هو المحرر المفضل لديك، لا بد أن تجرب جميع المحرِّرات. ترجمة -وبتصرف- للفصل Code Editors من كتاب The JavaScript Language انظر أيضًا المقال التالي: المثال الأول: أهلًا بالعالم! المقال السابق: أدوات المطور كامل مقالات دليل تعلم جافاسكربت
  8. أبقِ في بالك أن الشيفرة البرمجية عرضةً لاحتواء الكثير من الأخطاء، إذ احتمال ارتكابك الأخطاء كبير أثناء كتابة الشيفرة البرمجية، لا بل وقوعك فيها هو أمر حتمي طالما أنك إنسان ولست رجلًا آليًا. هل تصدق أنه حتى المبرمجين المتمرسين وذوي الخبرة الطويلة يرتكبون الكثير من الأخطاء في الشيفرة التي يكتبونها! لا تقلق فهذا أمر طبيعي. على أي حال، لا تُظهِر المتصفِّحات الأخطاء البرمجية تلقائيًا للمستخدمين. وعند وجود مشكلة ما في السكربت، ولا يمكنك آنذاك تحديد مكانها، وبالتالي لا يمكن إصلاحها. لذلك، أُضيفت «أدوات المطوّر» (developer tools) إلى المتصفِّحات لاسكتشاف الأخطاء وتوفير معلومات مفيدة عن السكربت لتحسينه. يفضل معظم المطورون العمل على متصفِّحي Chrome أو FireFox لاحتوائهما على أفضل أدوات المطوّر. توفر المتصفِّحات الأخرى أيضًا مجموعة أدوات للمطوّر والتي من الممكن أن تحتوي على مزايا خاصة. لكن عادةً ما تحاول اللحاق بمتصفِّحي Chrome و FireFox الأفضل من هذه الناحية. يفضل المطوّرون بشكل عام العمل على متصفِّح واحد وينتقلون إلى متصفِّح آخر عندما تكون المشكلة التي يعملون عليها محدَّدة بهذا المتصفِّح. بناءً على ذلك، نجد أنَّ أدوات المطور مهمة للغاية لما تمتلكه من مزايا تساعدك أثناء مسيرتك في تطوير الويب عبر JavaScript. سنتعلم في البداية طريقة فتحها، واستخدامها لاستكشاف الأخطاء، وتشغيل تعليمات JavaScript ضمنها. أدوات المطور في متصفح Google Chrome قم بفتح الصفحة bug.html. يوجد خطأ في الشيفرة المكتوبة بلغة JavaScript غير ظاهر للزائر العادي، لذا سنستخدم أدوات المطوّر لاكتشافه. اضغط على F12 (أو الاختصار Cmd+Opt+J إذا كنت تستخدم نظام التشغيل «ماك») وسيفتح ذلك تلقائيًا أدوات المطوّر على لسان «الطرفية» (Console). وتظهر أدوات المطوّر تقريبًا بهذا الشكل: يعتمد شكل أدوات المطوّر على إصدار متصفِّح Chrome الذي تستخدمه، إذ يختلف بشكل بسيط من إصدار إلى آخر. بإمكانك رؤية رسالة الخطأ باللون الأحمر. معنى الرسالة أن السكربت يحتوي على أمر غير معروف هو "lalala". لاحظ في أقصى اليمين وجود رابط إلى المصدر bug.html:12 مع رقم سطر الخطأ في الشيفرة. يظهر تحت رسالة الخطأ الرمز < باللون الأزرق، ويحدد «سطر الأوامر» (command line) الذي سنكتب عنده أوامر وتعليمات JavaScript. اضغط زر الإدخال Enter لتنفيذ الأمر بعد كتابته (أو Shift+Enter للانتقال إلى السطر التالي عند إدخال أمر متعدد الأسطر). الآن أصبح بإمكانك استكشاف الأخطاء، وهذا يكفي كبداية وسنعود لاحقًا إلى أدوات المطوَر لندرس استكشاف الأخطاء وإصلاحها أو ما يعرف debugging في فصل تنقيح الأخطاء في المتصفِّح Chrome. أدوات المطور في متصفحي FireFox و Safari وغيرهما تَستخدِم معظم المتصفِّحات الاختصار F12 لفتح أدوات المطوَر. بشكل عام تتشابه هذه الأدوات في الشكل والمضمون. وبمجرد تعلمك العمل على إحدى هذه الأدوات (بإمكانك البدء مع Chrome)، يمكنك بسهولة الانتقال للعمل على الأدوات الأخرى. أدوات المطور في متصفح Safari يختلف المتصفِّح Safari (متصفِّح خاص بنظام التشغيل «ماك» وغير مدعوم من قبل «ويندوز» أو «لينكس») في طريقة فتح أدوات المطور. نحتاج في البداية لتفعيل « قائمة المطوّر» (Develop menu). لفعل ذلك، افتح «التفضيلات» (Preferences) ثم اختر قائمة «متقدم» (Advanced). يوجد في الأسفل مربع اختيار لإظهار قائمة المطوَر في شريط القائمة. حدده لتفعيل القائمة: بإمكانك استعمال الاختصار Cmd+opt+C لإظهار وإخفاء الطرفية من أدوات المطور. ويمكنك ملاحظة ظهور قائمة جديدة في الأعلى اسمها «Develop». تملك هذه القائمة العديد من الخيارات والأوامر الخاصة بالمطور. الإدخال متعدد الأسطر عادةً يتم تنفيذ الشيفرة البرمجية في نافذة الأوامر سطرًا تلو الآخر عند الضغط على زر الإدخال Enter. ولكتابة أمر متعدد الأسطر، اضغط على Shift+Enter (يُمكِّنك ذلك من الانتقال إلى السطر التالي دون تنفيذ السطر الحالي، وعند الانتهاء من إدخال كامل الأمر، اضغط على Enter فقط لتنفيذ هذا الأمر المتعدد الأسطر). الخلاصة توفِّر أدوات المطوّر لك عدة أدوات متطورة تساعدك على تنقيح الأخطاء، وتنفيذ الأوامر، وفحص المتغيرات، وغيرها من المهام. يمكن الوصول إليها باستخدام الاختصار F12 في معظم متصفِّحات نظام Windows. أمَا في نظام Mac، استخدم الاختصار Cmd+Opt+J لمتصفِّح Chrome، واستخدم Cmd+Opt+C لمتصفِّح Safari (ولكن عليك أن تفعَل قائمة المطوّر في البداية). الآن أصبحت البيئة جاهزة لديك. استعد للتعمق في لغة JavaScript في الفصل التالي. ترجمة -وبتصرف- للفصل Developer Console من كتاب The JavaScript Language انظر أيضًا المقال التالي: محررات الشيفرة البرمجية المقال السابق: مقدمة إلى لغة JavaScript كامل مقالات دليل تعلم جافاسكربت
  9. تستخدَم لغة JavaScript لإنشاء صفحات ويب تفاعلية، وهي منتشرة بشكل كبير ومُستعمَلة من أغلبية المواقع، وتدعمها جميع المتصفحات تقريبًا دون الحاجة إلى إضافات خارجية. يشرح هذا المقال مزايا لغة JavaScript، وما يمكنك تحقيقه باستخدامها، وأفضل التقنيات التي تعمل معها بشكل جيد. ما هي لغة JavaScript؟ ظهرت لغة JavaScript لإنشاء صفحات ويب حيوية وتفاعلية. تسمى البرامج المكتوبة بلغة JavaScript بالسكربتات (scripts)، ويمكن كتابتها بشكل مباشر ضمن شيفرة HTML لصفحة الويب ليتم تنفيذها تلقائيًا عند تحميل الصفحة. ولا تحتاج هذه السكربتات إلى تحضير خاص أو تصريف مسبق وإنما تتم كتابتها ثم تنفيذها كنص عادي. هذا الأمر يميز لغة JavaScript عن لغة برمجية أخرى تشبهها بالاسم تدعى Java. لماذا سميت JavaScript؟ عندما ظهرت لغة JavaScript، كان لها اسم مختلف وهو «LiveScript» ولكن الشعبية الكبيرة للغة Java في تلك الفترة دفعت إلى تغيير اسم اللغة إلى JavaScript بهدف إظهارها بصورة «الأخ الصغير» للغة Java واكتساب بعض الشهرة منها. ومع تطور لغة JavaScript، أصبحت لغةً مستقلة بشكل كامل ولها مواصفات ومعايير خاصة بها تُسمى «ECMAScript»، ولم يعد لها أي علاقة بلغة Java. في الوقت الحالي لا يقتصر تنفيذ لغة JavaScript على المتصفح وإنما من الممكن تنفيذها ضمن الخادوم أيضًا، أو أي جهاز يحتوي على برنامج خاص يسمى محرك JavaScript. يحتوي المتصفح على محرك مدمج ضمنه عادةً ما يسمى بآلة JavaScript الافتراضية وله أسماء تختلف باختلاف المتصفحات. فمثلًا يسمى المحرك باسم: V8 في متصفحي Chrome و Opera وباسم SpiderMonkey في المتصفح FireFox. Trident و Chakra في إصدارات مختلفة من IE، ويسمى ChakraCore في MicroSoftEdge، ويسمى Nitro و SquirrelFish في متصفح Safari …إلخ. احفظ هذه الأسماء في ذهنك جيدًا لأنها مستخدمة بشكل كبير في مقالات المطورين عبر الإنترنت وسنأتي على ذكرها لاحقًا في مقالاتنا. إذا قرأت مثلًا الجملة التالية: «الخاصية X مدعومة من قبل V8»، فيجب أن تعرف أنَ هذه الخاصية تعمل على الأغلب ضمن المتصفحين Opera و Chrome. كيف تعمل محركات JavaScript؟ طريقة عمل المحركات معقدَة وتتألف من ثلاث مراحل أساسية: بدايةً، يقرأ المحرك (إذا كان التنفيذ يتم عن طريق المتصفح فالمحرك مدمج ضمنه) أو يفسر (بمعنى أدق) السكربت، ثم يحول السكربت إلى لغة الآلة (عملية التصريف)، ثم تُنفَّذ شيفرات الآلة بشكل سريع. يحسّن المحرك كل مرحلة من هذه العملية عن طريق مراقبة السكربت المترجم أثناء تنفيذه، وتحليل تدفق البيانات وفق السكربت ثم يقوم بتحسين شيفرة الآلة الناتجة وفقًا للمعرفة التي قام باكتسابها مما يساعد على زيادة سرعة تنفيذ السكربت. ما الذي يمكن أن تفعله لغة JavaScript ضمن المتصفح؟ لغة JavaScript بإصدارها الحالي هي لغة برمجية «آمنة». ويعود ذلك إلى توجيه هذه اللغة للعمل ضمن المتصفحات لذلك فهي لا تحتوي على تعليمات للوصول إلى طبقة أدنى من العتاد مثل المعالج أو الذاكرة لأن عملها لا يتطلب ذلك. وتعتمد امكانيات لغة JavaScript بشكل كبير على البيئة التي تعمل ضمنها؛ فمثلًا تدعم بيئة Node.Js (التي تنفِّذ شيفرة JavaScript خارج بيئة المتصفح) التوابع التي تسمح بالقراءة من أو الكتابة على الملفات، وتنفِّذ طلبات الشبكة، وغيرها من المهام التي لا يمكن تنفيذها في بيئة المتصفح. أما ضمن المتصفح، فيمكن للغة JavaScript القيام بجميع الأعمال المتعلقة بمعالجة صفحات الويب، والتحكم بالتفاعل بين المستخدم وخادم الويب. يمكن للغة JavaScript ضمن المتصفح تنفيذ العديد من المهام نذكر منها: إضافة عناصر HTML جديدة إلى الصفحة، وتغيير المحتوى الحالي لها، وتعديل التنسيقات. التفاعل مع المستخدم وتنفيذ أعمال معينة عند النقر على الفأرة وتحريك المؤشر والضغط على أزرار لوحة المفاتيح. إرسال الطلبات عبر الإنترنت للخوادم البعيدة، بالإضافة إلى تحميل وتنزيل الملفات (كما في تقنية AJAX و COMET). الحصول على معلومات من «ملفات تعريف الارتباط» (Cookies، أو الكعكات) والتعديل عليها، وطرح الأسئلة على زوار الموقع وإظهار الرسائل والاشعارات. يمكن استخدامها لتخزين البيانات من جهة المستخدم أي ذاكرةً محليةً. ما المهام التي لا يمكن للغة JavaScript القيام بها ضمن المتصفح؟ الحد من إمكانيات JavaScript ضمن المتصفح أمرٌ بالغ الضرورة وذلك لضمان أمان المستخدم. أي أن الهدف من ذلك هو منع صفحات الويب الخطيرة من الوصول إلى معلومات سرية أو التلاعب ببيانات المستخدم ...إلخ. يوجد العديد من القيود على عمل JavaScript ضمن المتصفح نذكر منها: لا يمكن للغة JavaScript ضمن المتصفح قراءة الملفات الموجودة على القرص الصلب للمستخدم، أو نسخها، أو التعديل عليها. كما لا يمكنها تشغيل البرامج على جهاز المستخدم أو الوصول إلى ملفات نظام التشغيل. تسمح المتصفحات في الوقت الحالي للغة JavaScript بالتعامل مع الملفات في حالة سماح المستخدم بذلك. مثال على ذلك هو تحميل المستخدم ملفًا ما إلى موقع ويب طلب ذلك إما عبر السحب والإفلات في مربع محدَّد أو اختيار ملف معين في الوسم <input>. وتوجد طرق تتيح التعامل مع الأجهزة الملحقة مثل الكاميرا أو مسجل الصوت ولكنها تتطلب تقديم صلاحيات صريحة من قبل المستخدم وأخذ موافقته على أداء مهمة معينة فقط. بمعنى أن الصفحة التي جرى تفعيل JavaScript لا يعني بالضرورة تفعيل كاميرات الويب والوصول إليها الأمر الذي يتيح مراقبة المستخدم ومحيطه وإرسال المعلومات عبر الإنترنت إلى وكالات الأمن القومي كما يظن البعض. في الحالة العامة، الألسن والنوافذ المختلفة في المتصفح لا يمكنها تبادل البيانات فيما بينها أو معرفة أية تفاصيل عن بعضها بعضًا إلا عندما تستخدم صفحة JavaScript لفتح صفحة أخرى؛ وحتى في هذه الحالة، لا يمكن لصفحة تبادل البيانات مع صفحة فتحتها إذا كانت هاتين الصفحتين من موقعين مختلفين (نطاق مختلف، برتوكول أو منفذ). يسمى ذلك «سياسة المصدر الواحد» ويمكن تجاوزها عند الحاجة ولكن يجب أن تحتوي كلا الصفحتين على سكربت JavaScript خاص يتحكم بتبادل البيانات بينهما. هذه المحدودية - مرةً أخرى - ضرورية لضمان أمان المستخدم. فلا يجب على أي صفحة من الموقع http://anysite.com مثلًا والتي فتحها المستخدم أن يكون باستطاعتها الوصول وسرقة بيانات صفحة أخرى من الموقع http://gmail.com مثلًا مفتوحة في لسان آخر من نفس المتصفح. بإمكان لغة JavaScript تبادل البيانات عبر الإنترنت بسهولة بين صفحة الويب والخادم الخاص بها ولكن إمكانيتها على استقبال البيانات من مواقع ونطاقات أخرى محدودة إلا في حالة السماح بذلك بتصريح صريح (يُذكَر ضمن ترويسة HTTP) للطرف الآخر البعيد. هذه المحدودية مرةً أخرى ضرورية لأمان المستخدم. يجب التنويه أنَ المحدوديات السابقة توجد فقط عند استخدام لغة JavaScript ضمن المتصفح ولا توجد عند استخدامها ضمن بيئة مختلفة مثل الخادم. كما أنّ المتصفحات في الوقت الحالي توفر ملحقات/إضافات تسأل المستخدم عن الرغبة بإعطاء صلاحيات أكبر للغة JavaScript المنفذة في المتصفح. ما المميز في لغة JavaScript؟ هنالك على الأقل ثلاثة أمور تميَز لغة JavaScript وهي: الاندماج الكامل مع HTML و CSS. سهولة تنفيذ الأمور البسيطة. مدعومة من قبل أغلبية المتصفحات ومفعًلة تلقائيًا. لغة JavaScript هي اللغة الوحيدة التي تتوفر فيها هذه المزايا الثلاث. وهذا ما يجعلها الأداة الأكثر انتشارًا لبناء صفحات الويب. قبل البدء بتعلم لغة JavaScript، من المفيد الاطلاع على الآفاق المستقبلية لها والتقنيات الحديثة التي تنافسها من لغات برمجية جديدة وتحديثات في عمل المتصفحات. اللغات المعتمدة على لغة JavaScript لا تناسب قواعد كتابة لغة JavaScript الجميع. ويختلف المطورون في حاجاتهم إلى مزايا مختلفة، وهذا بالطبع أمر متوقع لاختلاف مشاريعهم ومتطلباتهم. لذلك، ظهرت مؤخرًا مجموعة من اللغات البرمجية الجديدة والتي تُحوَّل (transpiled) إلى لغة JavaScript قبل تنفيذها في المتصفح. ومع تطور هذه الأدوات، أصبحت عملية التحويل (transpilation) سريعة. الأمر الذي سمح للمطورين بكتابة الشيفرات بلغة برمجية أخرى ليتم تحويلها تلقائيًا دون أي اختلاف إلى لغة JavaScript وكأنها مكتوبة من الأصل بهذه اللغة. بعض الأمثلة عن مثل هذه اللغات هي: CoffeeScript: تعدُّ لغةً ذات صياغة تجميلية للغة JavaScript. توفر صياغة أقصر مما يسمح بكتابة شيفرة برمجية أوضح وأكثر دقةً. لها شعبية بين مطوري لغة Ruby . TypeScript: تركز على إضافة تعريف لأنواع المعطيات لتسهيل دعم وتطوير الأنظمة المعقدة. طُوِّرت هذه اللغة من قبل شركة Microsoft. Dart: هي لغة مستقلة ولها محرك خاص وتعمل على بيئات مختلفة غير المتصفح (مثل تطبيقات الموبايل). قدمتها شركة Google كبديل عن لغة JavaScript، ولكن تعمل المتصفحات في الوقت الحالي على تحويلها إلى لغة JavaScript كما هو حال اللغات السابقة. هنالك المزيد من اللغات ولكن تعلمك واستخدامك لإحداها لا يلغي ضرورة تعلمك للغة JavaScript، إذ يجب تعلم وفهم هذه اللغة لمعرفة كيفية تنفيذ العمليات والوظائف المختلفة بشكل فعلي. على أي حال، تبقى لغة JavaScript هي الأشهر والأقوى والأسرع تطورًا بين اللغات الشبيهة والمنافسة لها. الخلاصة أُوجدت لغة JavaScript في البداية كلغة يتم تنفيذها فقط من قبل المتصفح ثم تطورت وأصبح من الممكن تنفيذها ضمن بيئات مختلفة عبر Node.js. اليوم، تملك لغة JavaScript مكانة كبيرة وخاصة بسبب دعمها من قبل معظم المتصفحات واندماجها الكامل مع HTML و CSS. هنالك العديد من اللغات التي تُحول إلى JavaScript وتوفر مزايا خاصة. لذا ننصحك بالاطلاع عليها ولو بشكل سريع بعد تمكنك من لغة JavaScript. ترجمة -وبتصرف- للفصل An Introduction to JavaScript من كتاب The JavaScript Language انظر أيضًا المقال التالي: أدوات المطور محررات الشيفرة البرمجية كامل مقالات دليل تعلم جافاسكربت
×
×
  • أضف...