بناء جملة جافا سكريبت

إن بناء جملة جافا سكريبت هو مجموعة القواعد التي تحدد برنامج جافا سكريبت منظم بشكل صحيح.
تستخدم الأمثلة أدناه الوظيفة console.log()الموجودة في معظم المتصفحات لإخراج النصوص القياسية .
تفتقر مكتبة جافا سكريبت القياسية إلى دالة إخراج نص قياسية رسمية (باستثناء دالة `print` document.write). ونظرًا لأن جافا سكريبت تُستخدم بشكل أساسي في برمجة جانب العميل ضمن متصفحات الويب الحديثة ، ولأن جميع متصفحات الويب تقريبًا توفر دالة `alert`، alertفإنه يمكن استخدام دالة `print` أيضًا، ولكنها ليست شائعة الاستخدام.
تتمتع لغة TypeScript ، التي توسع لغة JavaScript بإضافة تعليقات توضيحية للأنواع وميزات إضافية، بنفس الصيغة بالإضافة إلى ميزاتها الإضافية الخاصة.
الأصول

لخص بريندان إيتش أصل بناء الجملة في الفقرة الأولى من مواصفات جافا سكريبت 1.1 [ 1 ] [ 2 ] على النحو التالي:
تستعير لغة جافا سكريبت معظم تركيبها النحوي من جافا ، ولكنها ترث أيضًا من أوك وبيرل ، مع بعض التأثير غير المباشر من سيلف في نظام النموذج الأولي للكائنات.
تُشتق بنية لغة جافا سكريبت في الغالب من بنية لغة جافا ، والتي بدورها مشتقة من بنية لغة سي وبنية لغة سي++ .
الأساسيات
الكلمات المفتاحية
الكلمات المحجوزة
الكلمات التالية هي كلمات مفتاحية.
breakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumevalexportextendsfinallyforfunctionifimportininstanceofnewreturnsuperswitchthisthrowtrytypeofusingvarvoidwhilewith
الكلمات المحجوزة في الوضع الصارم
الكلمات التالية هي كلمات مفتاحية في الوضع الصارم.
letimplementsinterfacestaticpackageprivateprotectedpublicyield
الكلمات المحجوزة في كود الوحدة أو جسم الدالة غير المتزامنة
الكلمات التالية هي كلمات مفتاحية في كود الوحدة أو جسم الدالة غير المتزامنة
await
القيم الحرفية
تشير الكلمات التالية إلى القيم الحرفية المستخدمة في اللغة.
truefalsenull
تُعرّف لغة جافا سكريبت أيضًا الثوابت العامة التالية، والتي ليست كلمات مفتاحية.
NaNInfinityundefined
الكلمات الرئيسية المحذوفة
تمت إزالة الكلمات التالية، المرتبطة بشكل أساسي بلغة جافا، من معيار ECMAScript 5/6:
abstractbooleanbytechardoublefinalfloatgotointlongnativeshortsynchronizedthrowstransientvolatile
كلمات مفتاحية في TypeScript
الكلمات الإضافية التالية هي كلمات مفتاحية في لغة تايب سكريبت.
abstractanyasdeclareinferkeyofmodulenamespaceneverreadonlytypeunknown
حساسية حالة الأحرف
لغة جافا سكريبت حساسة لحالة الأحرف . من الشائع أن يبدأ اسم الدالة البانية بحرف كبير ، واسم الدالة أو المتغير بحرف صغير.
مثال:
var a = 5 ; console.log ( a ) ; // 5 console.log ( A ) ; // يُظهر خطأ ReferenceError: A غير مُعرّفةالمسافات البيضاء والفواصل المنقوطة
على عكس لغة C ، يمكن أن تؤثر المسافات البيضاء في كود جافا سكريبت بشكل مباشر على دلالات الكود . تُنهي الفواصل المنقوطة العبارات في جافا سكريبت. وبسبب خاصية الإدراج التلقائي للفواصل المنقوطة ، تُعتبر بعض العبارات التي تُصاغ بشكل صحيح عند تحليل سطر جديد مكتملة، كما لو أُدرجت فاصلة منقوطة قبل السطر الجديد مباشرةً. ينصح بعض الخبراء بتحديد الفواصل المنقوطة التي تُنهي العبارات بشكل صريح، لأن ذلك قد يُقلل من الآثار غير المقصودة للإدراج التلقائي للفواصل المنقوطة. [ 3 ]
هناك مشكلتان: يمكن أن تبدأ خمسة رموز جملة أو تكون امتدادًا لجملة كاملة؛ وخمسة قواعد إنتاج مقيدة، حيث لا يُسمح بفواصل الأسطر في مواضع معينة، مما قد يؤدي إلى تحليل غير صحيح.
الرموز الخمسة الإشكالية هي: (القوس المفتوح " "، والقوس المعقوف المفتوح " ["، والشرطة المائلة " /"، وعلامة الجمع " +"، وعلامة الطرح " -". من بين هذه الرموز، يُعد القوس المفتوح شائعًا في نمط تعبير الدالة المُستدعى مباشرةً ، ويظهر القوس المعقوف المفتوح أحيانًا، بينما تُعدّ الرموز الأخرى نادرة جدًا. مثال:
a = b + c ( d + e ). foo ()// يتم التعامل معها على النحو التالي: // a = b + c(d + e).foo();مع اقتراح إنهاء العبارة السابقة بفاصلة منقوطة.
يقترح البعض بدلاً من ذلك استخدام الفاصلة المنقوطة في بداية الأسطر التي تبدأ بـ ' (' أو ' ['، حتى لا يتم ربط السطر بالسطر السابق عن طريق الخطأ. يُعرف هذا بالفاصلة المنقوطة الوقائية ، ويُستخدم لأن الكود قد يصبح غامضًا عند إعادة ترتيبه. على سبيل المثال:
a = b + c ( d + e ). foo ()// تُعامل على النحو التالي: // a = b + c; // (d + e).foo();تُستخدم الفواصل المنقوطة أحيانًا في بداية أسماء مكتبات جافا سكريبت، تحسبًا لإضافتها إلى مكتبة أخرى لا تستخدم الفواصل المنقوطة في نهايتها، إذ قد يُؤدي ذلك إلى غموض في العبارة الأولى. في هذه الحالة، حيث قد يكون موضع الفواصل المنقوطة غير معتاد، يُفضّل وضعها يدويًا في نهاية العبارات.
الإنتاجات الخمسة المقيدة هي return: و throw، و break، continueو ، و والزيادة/النقصان اللاحق. في جميع الحالات، لا يؤدي إدخال الفواصل المنقوطة إلى حل المشكلة، ولكنه يجعل الصيغة المُحللة أكثر وضوحًا، مما يُسهل اكتشاف الخطأ. تأخذ returnو throwقيمة اختيارية، بينما تأخذ breakو continueتسمية اختيارية. في جميع الحالات، يُنصح بوضع القيمة أو التسمية على نفس سطر العبارة. يظهر هذا غالبًا في عبارة الإرجاع، حيث قد يُرجع المرء كائنًا حرفيًا كبيرًا، والذي قد يُوضع عن طريق الخطأ بدءًا من سطر جديد. بالنسبة للزيادة/النقصان اللاحق، يوجد غموض محتمل مع الزيادة/النقصان السابق، ومرة أخرى يُنصح بوضعها على نفس السطر.
أعد a + b ;// تُرجع قيمة غير مُعرَّفة. تُعامل على النحو التالي: // return; // a + b; // يجب كتابتها على النحو التالي: // return a + b;تعليقات
صيغة التعليقات هي نفسها في لغات البرمجة C++ و Swift وغيرها.
تبدأ التعليقات ذات السطر الواحد بـ //وتستمر حتى نهاية السطر. ويمكن أيضاً إنشاء نوع ثانٍ من التعليقات؛ تبدأ هذه التعليقات بـ /*وتنتهي بـ */ويمكن استخدامها للتعليقات متعددة الأسطر.
أما النوع الثالث من التعليقات، وهو تعليق الهاش بانج، فيبدأ بـ #!ويستمر حتى نهاية السطر. وهو صالح فقط في بداية الملفات ومخصص للاستخدام في بيئات سطر الأوامر . [ 4 ]
# ! تعليق هاشبانغ// تعليق من سطر واحد/* تعليق متعدد الأسطر */المتغيرات
لا تُحدد أنواع المتغيرات في جافا سكريبت القياسية ، لذا يُمكن تخزين أي قيمة (لكل قيمة نوع) في أي متغير. بدءًا من ES6 ، الإصدار السادس من اللغة، يُمكن تعريف المتغيرات باستخدام `input` varللمتغيرات ذات النطاق الوظيفي، و` input` letأو const`input` للمتغيرات ذات النطاق الكتلي . قبل ES6، كان يُمكن تعريف المتغيرات فقط باستخدام varعبارة `input`. لا يُمكن تغيير القيم المُسندة إلى المتغيرات المُعرّفة باستخدام `input` const، ولكن يُمكن تغيير خصائصها. varيُنصح بعدم استخدام `input` نظرًا لأن letالمتصفحات constالحديثة تدعم `input` و`input`. [ 5 ] يجب أن يبدأ مُعرّف المتغير بحرف أو شرطة سفلية ( __) أو علامة دولار ($ $)، بينما يُمكن أن تكون الأحرف اللاحقة أرقامًا ( 0-9$). جافا سكريبت حساسة لحالة الأحرف، لذا فإن الأحرف الكبيرة من " A " إلى " Z " تختلف عن الأحرف الصغيرة من " a " إلى " z ".
ابتداءً من JavaScript 1.5، يُمكن استخدام أحرف ISO 8859-1 أو Unicode (أو تسلسلات الهروب Unicode) في المعرّفات. [ 6 ] في بعض تطبيقات JavaScript، يُمكن استخدام علامة @ في المعرّف ، ولكن هذا يُخالف المواصفات ولا تدعمه التطبيقات الأحدث.\uXXXX
النطاقات والرفع
varتكون المتغيرات المُعلنة باستخدام ` var` محصورةً في نطاق الدالة ، بينما تكون المتغيرات المُعلنة باستخدام `var` letأو ` constvar` محصورةً في نطاق الكتلة . وبما أن التصريحات تُعالج قبل تنفيذ أي كود، فإنه يُمكن إسناد قيمة لمتغير واستخدامه قبل الإعلان عنه في الكود. [ 7 ] يُشار إلى هذا بـالرفع ، وهو ما يعادلتعريف المتغيرات مسبقًافي أعلى الدالة أو الكتلة. [ 8 ]
باستخدام عبارات var`if` letو`if` و`if` const، يتم رفع تعريف المتغير فقط، بينما لا يتم رفع قيمه. وبالتالي، فإن عبارة `if` في منتصف الدالة تُعادل عبارة تعريف في بداية الدالة، وعبارة إسناد في نفس الموضع من منتصف الدالة. هذا يعني أنه لا يمكن الوصول إلى القيم قبل تعريفها؛ أي أن الإشارة إليها مسبقًا غير ممكنة. تبقى قيمة المتغير ثابتة حتى يتم تهيئته. لا يمكن الوصول إلى المتغيرات المُعرَّفة باستخدام ` if` أو `if` إلا بعد تهيئتها، لذا فإن الإشارة إلى هذه المتغيرات قبل ذلك سيؤدي إلى حدوث خطأ.varx=1varxx=1varundefinedletconst
تُشبه تعريفات الدوال، التي تُعرّف متغيرًا وتُسند إليه دالة ، عبارات المتغيرات، ولكن بالإضافة إلى رفع التعريف، فإنها ترفع أيضًا الإسناد - كما لو أن العبارة بأكملها تظهر في بداية الدالة المُحتوية - وبالتالي يُمكن أيضًا الإشارة إلى المتغير: فموقع عبارة الدالة داخل الدالة المُحيطة غير مهم. وهذا يختلف عن إسناد تعبير دالة إلى متغير في عبارة var`function` letأو `function` أو ` constfunction`.
فعلى سبيل المثال،
var func = function () { .. } // يتم رفع التصريح فقط function func () { .. } // يتم رفع التصريح والإسناديمكن إنشاء نطاق الكتلة عن طريق تغليف الكتلة بأكملها في دالة ثم تنفيذها - وهذا ما يُعرف بنمط تعبير الدالة المستدعاة على الفور - أو عن طريق تعريف المتغير باستخدام الكلمة letالمفتاحية.
إعلان وتخصيص
المتغيرات المُعلنة خارج نطاق معين تُعتبر متغيرات عامة . أما إذا تم الإعلان عن متغير في نطاق أعلى، فيمكن الوصول إليه من النطاقات الفرعية.
عندما يحاول جافا سكريبت تحديد مُعرِّف، فإنه يبحث في النطاق المحلي. إذا لم يجد هذا المُعرِّف، فإنه يبحث في النطاق الخارجي التالي، وهكذا على امتداد سلسلة النطاقات حتى يصل إلى النطاق العام حيث توجد المتغيرات العامة. إذا لم يجده بعد ذلك، فسيُصدر جافا سكريبت ReferenceErrorاستثناءً.
عند تعيين مُعرِّف، يتبع جافا سكريبت نفس العملية تمامًا لاسترجاع هذا المُعرِّف، باستثناء أنه إذا لم يُعثر عليه في النطاق العام ، فسيتم إنشاء "المتغير" في النطاق الذي تم إنشاؤه فيه. [ 9 ] ونتيجةً لذلك، يصبح المتغير الذي لم يُصرَّح عنه عامًا إذا تم تعيينه. كما أن تعريف متغير (باستخدام الكلمة المفتاحية `var` var) في النطاق العام (أي خارج أي جسم دالة (أو كتلة في حالة `let`/`const`))، أو تعيين مُعرِّف لم يُصرَّح عنه، أو إضافة خاصية إلى الكائن العام (عادةً `window` ) سيؤدي أيضًا إلى إنشاء متغير عام جديد.
لاحظ أن الوضع الصارم في جافا سكريبت يمنع تعيين متغير غير معلن، مما يتجنب تلوث مساحة الأسماء العامة.
أمثلة
فيما يلي بعض الأمثلة على تعريفات المتغيرات ونطاقها:
var x1 = 0 ; // متغير عام، لأنه ليس ضمن أي دالة let x2 = 0 ; // متغير عام أيضًا، هذه المرة لأنه ليس ضمن أي كتلةدالة f () { متغيران محليان z = 'foxes' و r = 'birds' ; // متغيران محليان m = 'fish' ; // متغير عام، لأنه لم يتم تعريفه في أي مكان من قبلfunction child () { var r = 'monkeys' ; // هذا المتغير محلي ولا يؤثر على متغير "birds" r الخاص بالدالة الأصلية. z = 'penguins' ; // إغلاق: يمكن للدالة الفرعية الوصول إلى متغيرات الدالة الأصلية. }twenty = 20 ; // تم تعريف هذا المتغير في السطر التالي، ولكن يمكن استخدامه في أي مكان في الدالة، حتى قبل ذلك، كما هو الحال هنا var twenty ;child (); return x1 + x2 ; // يمكننا استخدام x1 و x2 هنا، لأنهما متغيران عامان }f ();console.log ( z ); // سيؤدي هذا السطر إلى ظهور استثناء ReferenceError، لأن قيمة z لم تعد متاحة .for ( let i = 0 ; i < 10 ; i ++ ) console.log ( i ) ; console.log ( i ) ; // يُظهر خطأ ReferenceError : i غير مُعرّفfor ( const i = 0 ; i < 10 ; i ++ ) console.log ( i ) ; // يُظهر خطأ TypeError: Assignment to constant variablefor ( const i of [ 1 , 2 , 3 ]) console.log ( i ); // لن يُثير هذا استثناءً. لا يتم إعادة تعيين قيمة i، بل يتم إنشاؤها من جديد في كل تكرار .const pi ; // يُطلق خطأً في بناء الجملة: مُهيئ مفقود في تعريف الثابتأنواع البيانات الأولية
توفر لغة جافا سكريبت ستة أنواع بيانات أساسية :
UndefinedNumberBigIntStringBooleanSymbol
توفر بعض أنواع البيانات الأولية أيضًا مجموعة من القيم المسماة التي تمثل نطاق حدود النوع. وسيتم شرح هذه القيم المسماة في الأقسام المناسبة أدناه.
غير محدد
تُسند القيمة "غير مُعرّفة" إلى جميع المتغيرات غير المُهيأة ، وتُعاد أيضًا عند التحقق من خصائص الكائن غير الموجودة. في سياق منطقي، تُعتبر القيمة "غير مُعرّفة" قيمة خاطئة.
ملاحظة: يُعتبر النوع غير المُعرَّف نوعًا بدائيًا حقيقيًا. ما لم يتم تحويله صراحةً، قد يتصرف النوع غير المُعرَّف بشكل غير متوقع مقارنةً بالأنواع الأخرى التي تُقيَّم إلى خطأ في سياق منطقي.
let test ; // تم تعريف المتغير، ولكن لم يتم تحديده، ... // ... تم تعيين قيمته إلى قيمة غير مُعرَّفة const testObj = {}; console.log ( test ); // المتغير test موجود، ولكن قيمته غير مُعرَّفة ... // ... يتم عرضها كقيمة غير مُعرَّفة console.log ( testObj.myProp ); // الكائن testObj موجود، ولكن الخاصية غير موجودة، ... // ... يتم عرضها كقيمة غير مُعرَّفة console.log ( undefined == null ) ; // لم يتم فرض النوع أثناء التحقق، ويتم عرض القيمة true console.log ( undefined === null ); // تم فرض النوع أثناء التحقق، ويتم عرض القيمة falseملاحظة: لا يوجد تعريف حرفي مدمج في لغة البرمجة للقيمة غير المعرّفة. لذا، فإن هذه الطريقة ليست مضمونة للتحقق مما إذا كان المتغير غير معرّف، لأنه في الإصدارات السابقة لـ ECMAScript 5، كان من الممكن كتابة `undefined` . يُعدّ استخدام `undefined` طريقةً أكثر موثوقية للمقارنة .(x===undefined)varundefined="I'm defined now";(typeofx==='undefined')
لن تعمل وظائف كهذه كما هو متوقع:
دالة ` isUndefined ( x ) `: ` let u ; return x === u ; }` // هكذا... دالة ` isUndefined ( x ) `: ` return x === void 0 ; }` // ... أو تلك الثانية دالة ` isUndefined ( x ) `: ` return ( typeof x ) === "undefined" ; } ` // ... أو تلك الثالثةهنا، يؤدي استدعاء الدالة isUndefined(my_var)إلى ظهور خطأ مرجعي إذا كان my_var معرفًا غير معروف، بينما لا يحدث ذلك.typeofmy_var==='undefined'
رقم
تُمثَّل الأرقام بالنظام الثنائي باستخدام معيار IEEE 754 للأعداد العشرية ذات الفاصلة العائمة . ورغم أن هذا التنسيق يوفر دقة تصل إلى 16 رقمًا معنويًا تقريبًا ، إلا أنه لا يستطيع دائمًا تمثيل الأعداد الحقيقية بدقة تامة، بما في ذلك الكسور.
يُصبح هذا الأمر إشكالياً عند مقارنة الأرقام أو تنسيقها. على سبيل المثال:
console.log ( 0.2 + 0.1 === 0.3 ); // يعرض القيمة false console.log ( 0.94 - 0.01 ); // يعرض القيمة 0.9299999999999999ونتيجة لذلك، يجب استخدام روتين مثل طريقة toFixed() لتقريب الأرقام كلما تم تنسيقها للإخراج .
يمكن تحديد الأرقام بأي من هذه الرموز:
345 ؛ // عدد صحيح، على الرغم من وجود نوع عددي واحد فقط في جافا سكريبت. 34.5 ؛ // عدد عشري. 3.45e2 ؛ // عدد عشري آخر، مكافئ لـ 345. 0b1011 ؛ // عدد صحيح ثنائي يساوي 11. 0o377 ؛ // عدد صحيح ثماني يساوي 255. 0xFF ؛ // عدد صحيح سداسي عشري يساوي 255، الأرقام ممثلة بـ ... // ... قد تكون الأحرف AF كبيرة أو صغيرة.يوجد أيضًا فاصل رقمي، وهو _ (الشرطة السفلية)، تم تقديمه في ES2021:
// ملاحظة: لا يدعم بناء جملة ويكيبيديا الفواصل الرقمية حتى الآن 1_000_000_000 ; // يُستخدم مع الأعداد الكبيرة 1_000_000 .5 ; // يدعم الأعداد العشرية 1_000e1_000 ; // يدعم الأسس// يدعم النظام الثنائي والثماني والسداسي عشري 0b0000_0000_0101_1011 ; 0o0001_3520_0237_1327 ; 0xFFFF_FFFF_FFFF_FFFE ;// لكن لا يمكن للمستخدمين استخدامها بجوار جزء رقمي غير رقمي، أو في البداية أو النهاية _12 ؛ // المتغير غير مُعرَّف (الشرطة السفلية تجعله مُعرِّف متغير) 12 _ ؛ // خطأ في بناء الجملة (لا يمكن أن يكون في نهاية الأرقام) 12 _ .0 ؛ // خطأ في بناء الجملة (لا معنى لوضع فاصل بجوار الفاصلة العشرية) 12. _0 ؛ // خطأ في بناء الجملة 12 e_6 ؛ // خطأ في بناء الجملة (بجوار "e"، وهو ليس رقمًا. لا معنى لوضع فاصل في البداية) 1000 ____0000 ؛ // خطأ في بناء الجملة (بجوار "_"، وهو ليس رقمًا. يُسمح بفاصل واحد فقط في كل مرة)يمكن الحصول على نطاقات +∞ و − ∞ و NaN (ليس رقمًا) لنوع الرقم من خلال تعبيرين برمجيين:
اللانهاية ؛ // اللانهاية الموجبة (والسالبة تُحصل عليها باستخدام -Infinity على سبيل المثال) NaN ؛ // قيمة "ليست رقمًا"، والتي تُعاد أيضًا كخطأ في ... // ... تحويلات السلسلة إلى رقماللانهاية و NaN هما أرقام:
typeof Infinity ; // تُرجع "رقمًا" typeof NaN ; // تُرجع "رقمًا"تتوافق هذه القيم الخاصة الثلاث وتتصرف كما هو موضح في معيار IEEE-754 .
يمكن استخدام مُنشئ Number (المستخدم كدالة)، أو عامل الجمع الأحادي + أو -، لإجراء تحويل رقمي صريح:
const myString = "123.456" ; const myNumber1 = Number ( myString ); const myNumber2 = + myString ;عند استخدامه كدالة إنشاء، يتم إنشاء كائن غلاف رقمي (على الرغم من أنه قليل الفائدة):
const myNumericWrapper = new Number ( 123.456 );لكن NaN لا يساوي نفسه:
ثابت نان = نان ; وحدة التحكم . سجل ( NaN == NaN )؛ // وحدة تحكم زائفة . سجل ( NaN === NaN )؛ // وحدة تحكم زائفة . سجل ( NaN !== NaN ); // وحدة التحكم الحقيقية . سجل ( نان !== نان )؛ // حقيقي// يمكن للمستخدمين استخدام دوال isNaN للتحقق من قيمة NaN . console.log ( isNaN ( " تم التحويل إلى NaN" )); // صحيح console.log ( isNaN ( NaN ) ) ; // صحيح console.log ( Number.isNaN ( "لم يتم التحويل" ) ) ; // خطأ console.log ( Number.isNaN ( NaN ) ) ; // صحيحBigInt
في جافا سكريبت، تُمثَّل الأعداد العادية بنوع الفاصلة العائمة IEEE 754، ما يعني أنه لا يمكن تخزين الأعداد الصحيحة بأمان إلا إذا كانت قيمتها تقع بين 0 Number.MIN_SAFE_INTEGERو Number.MAX_SAFE_INTEGER1. [ 10 ] أما BigInt فتُمثِّل أعدادًا صحيحة بأي حجم، مما يسمح للمبرمجين بتخزين أعداد صحيحة أكبر أو أصغر من أن تُمثَّل بصيغة IEEE 754. [ 11 ]
هناك طريقتان لتعريف قيمة من نوع BigInt. nيمكن إلحاقها بعدد صحيح، أو BigIntيمكن استخدام الدالة: [ 11 ]
const a = 12345n ; // إنشاء متغير وتخزين قيمة عددية كبيرة (BigInt) تساوي 12345 const b = BigInt ( 12345 );خيط
السلسلة النصية في جافا سكريبت هي تسلسل من الأحرف. في جافا سكريبت، يمكن إنشاء السلاسل النصية مباشرةً (كقيم حرفية) بوضع سلسلة الأحرف بين علامتي اقتباس مزدوجتين ( ") أو مفردتين ( '). يجب كتابة هذه السلاسل النصية على سطر واحد، ولكن يمكن أن تتضمن أحرف سطر جديد مُهرَّبة (مثل \n). يسمح معيار جافا سكريبت باستخدام علامة الاقتباس الخلفية ( `، والمعروفة أيضًا باسم علامة النبرة أو علامة التحديد الخلفية) لاقتباس السلاسل النصية الحرفية متعددة الأسطر، بالإضافة إلى التعبيرات المضمنة باستخدام الصيغة . [ 12 ]${expression}
const greeting = "مرحباً أيها العالم!" ; const anotherGreeting = "تحياتي، يا سكان الأرض." ; const aMultilineGreeting = "مع أطيب التحيات، جون دو."// تقوم القوالب الحرفية بتحويل أنواع التعبيرات المُقَيَّمة وإدراجها في السلسلة النصية. const templateLiteral = `هذا ما هو مُخزَّن في anotherGreeting: ${ anotherGreeting } .` ; console . log ( templateLiteral ); // 'هذا ما هو مُخزَّن في anotherGreeting: 'تحياتي، يا سكان الأرض.'' console . log ( `أنت ${ Math . floor ( age )=> 18 ? "مسموح" : "غير مسموح" } لعرض صفحة الويب هذه` );يمكن الوصول إلى الأحرف الفردية داخل سلسلة نصية باستخدام دالة charAt (المُقدمة من String.prototype ). هذه هي الطريقة المُفضلة للوصول إلى الأحرف الفردية داخل سلسلة نصية، لأنها تعمل أيضًا في المتصفحات القديمة.
const h = greeting.charAt ( 0 ) ;في المتصفحات الحديثة، يمكن الوصول إلى الأحرف الفردية داخل سلسلة نصية (كسلاسل نصية تحتوي على حرف واحد فقط) من خلال نفس طريقة ترميز المصفوفات:
const h = greeting [ 0 ];لكن سلاسل جافا سكريبت غير قابلة للتغيير :
greeting [ 0 ] = "H" ; // فشل.تطبيق عامل المساواة ("==") على سلسلتين نصيتين يُرجع القيمة "صحيح" إذا كانت السلسلتان لهما نفس المحتوى، أي: لهما نفس الطول وتحتويان على نفس تسلسل الأحرف (حالة الأحرف مهمة بالنسبة للأبجديات). وبالتالي:
const x = "World" ; const compare1 = ( "Hello, " + x == "Hello, World" ); // هنا compare1 تحتوي على القيمة true. const compare2 = ( "Hello, " + x == "hello, World" ); // هنا compare2 تحتوي على القيمة false لأن الأحرف الأولى من كلا المعاملين ليست من نفس الحالة.لا يمكن تداخل علامات الاقتباس من نفس النوع إلا إذا تم تهريبها .
let x = '"Hello, World!" he said.' ; // صحيح. x = "" Hello , World ! " he said." ; // غير صحيح. x = "\"Hello, World!" he said." ; // يعمل عن طريق استبدال علامة التنصيص المفردة " بعلامة \"يقوم مُنشئ String بإنشاء كائن سلسلة نصية (كائن يغلّف سلسلة نصية):
const greeting = new String ( "Hello, World!" );تحتوي هذه الكائنات على دالة valueOf التي تُعيد السلسلة النصية الأولية المُغلّفة بداخلها :
const s = new String ( "Hello!" ); typeof s ; // من نوع 'object'. typeof s.valueOf ( ); // من نوع 'string'.لا تتصرف عملية المساواة بين كائنين من نوع String كما هو الحال مع أنواع البيانات النصية الأساسية:
const s1 = new String ( "Hello!" ) ; const s2 = new String ( "Hello!" ); s1 == s2 ; // خطأ، لأنهما كائنان مختلفان. s1.valueOf () == s2.valueOf ( ); // صحيح .منطقي
توفر لغة جافا سكريبت نوع بيانات منطقيًا (Boolean) بقيمتين حرفيتين: صحيح (true ) وخطأ (false) . يُعيد عامل التشغيل `typeof` السلسلة النصية "boolean" لهذه الأنواع الأولية . عند استخدامه في سياق منطقي، تُقيّم القيم 0 ، و -0 ، و null ، و NaN ، و undefined ، والسلسلة النصية الفارغة ( "" ) على أنها خطأ (false) نظرًا للتحويل التلقائي للأنواع . أما جميع القيم الأخرى ( مكمل القائمة السابقة) فتُقيّم على أنها صحيح (true )، بما في ذلك السلاسل النصية "0" و "false" وأي كائن.
تحويل النوع
يمكن تجنب التحويل التلقائي للأنواع بواسطة عوامل مقارنة المساواة ( ==و !=) باستخدام عوامل مقارنة الأنواع التي تم التحقق منها ( ===و !==).
عندما يكون تحويل النوع مطلوبًا، يقوم جافا سكريبت بتحويل المعاملات المنطقية أو الرقمية أو النصية أو الكائنية على النحو التالي: [ 13 ]
- رقم وسلسلة نصية
- يتم تحويل السلسلة النصية إلى قيمة عددية. تحاول جافا سكريبت تحويل السلسلة النصية العددية إلى قيمة من نوع Number. أولًا، يتم استخلاص قيمة رياضية من السلسلة النصية العددية. ثم، يتم تقريب هذه القيمة إلى أقرب قيمة من نوع Number.
- منطقي
- إذا كان أحد المعاملات منطقيًا، فسيتم تحويل المعامل المنطقي إلى 1 إذا كان صحيحًا ، أو إلى 0 إذا كان خاطئًا .
- هدف
- عند مقارنة كائن برقم أو سلسلة نصية، يحاول جافا سكريبت إرجاع القيمة الافتراضية للكائن. يتم تحويل الكائن إلى قيمة أولية من نوع سلسلة نصية أو رقم باستخدام دالتي `valueOf()` أو `toString()` الخاصتين بالكائن. في حال فشل ذلك، يتم توليد خطأ أثناء التشغيل.
تحويل النوع المنطقي
يدعو دوغلاس كروكفورد إلى استخدام مصطلحي "صحيح" و"خاطئ" لوصف سلوك القيم من مختلف الأنواع عند تقييمها في سياق منطقي، لا سيما فيما يتعلق بالحالات الشاذة. [ 14 ] كانت عوامل التشغيل المنطقية الثنائية تُرجع قيمة منطقية في الإصدارات الأولى من جافا سكريبت، ولكنها الآن تُرجع أحد المعاملات بدلاً من ذلك. يُرجع المعامل الأيسر إذا كان من الممكن تقييمه على أنه : خطأ ( false) في حالة العطف ، أو صحيح (true ) في حالة الفصل ؛ وإلا يُرجع المعامل الأيمن. قد يختلف التحويل التلقائي للأنواع بواسطة عوامل المقارنة في حالات المعاملات المختلطة المتوافقة مع القيم المنطقية والأرقام (بما في ذلك السلاسل النصية التي يمكن تقييمها كرقم، أو الكائنات التي يمكن تقييمها كسلسلة نصية)، لأن المعامل المنطقي سيُقارن كقيمة عددية. قد يكون هذا غير متوقع. يمكن تحويل التعبير بشكل صريح إلى نوع منطقي أولي عن طريق مضاعفة عامل النفي المنطقي : ( !! )، أو باستخدام الدالة Boolean() ، أو باستخدام عامل الشرط : ( ).a && ba || bc ? t : f
// تحويل النوع تلقائيًا console.log ( true == 2 ) ; // خطأ... صحيح → 1 !== 2 ← 2 console.log ( false == 2 ); // خطأ... خطأ → 0 !== 2 ← 2 console.log ( true == 1 ) ; // صحيح.... صحيح → 1 === 1 ← 1 console.log(false == 0); // صحيح.... خطأ → 0 === 0 ← 0 console.log(true == " 2 " ) ; // خطأ ... صحيح → 1 ! == 2 ← " 2 " console.log ( false == " 2 " ) ; // خطأ ... خطأ → 0 !== 2 ← "2" console.log ( true == " 1" ); // صحيح.... صحيح → 1 === 1 ← "1" console.log ( false == " 0" ) ; // صحيح.... خطأ → 0 === 0 ← "0" وحدة التحكم . سجل ( خطأ == "" )؛ // صحيح.... خطأ → 0 === 0 ← "" console . سجل ( خطأ == نان )؛ // خطأ... خطأ → 0 !== NaNconsole.log ( NaN == NaN ); // خطأ...... NaN لا يكافئ أي شيء، بما في ذلك NaN .// مقارنة مُدققة النوع (بدون تحويل الأنواع والقيم) console.log ( true === 1 ); // خطأ ...... أنواع البيانات غير متطابقة// تحويل صريح للأنواع console.log ( true === !! 2 ); // صحيح... أنواع البيانات والقيم متطابقة console.log ( true === !! 0 ) ; // خطأ... أنواع البيانات متطابقة، لكن القيم مختلفة console.log( 1 ? true : false ) ; // صحيح ... ± 0 و NaN فقط هما أرقام "خاطئة" console.log ( " 0" ? true : false ); // صحيح... السلسلة الفارغة فقط هي "خاطئة" console.log ( Boolean ({})); // صحيح... جميع الكائنات "صحيحة "يمكن استخدام عامل التشغيل `new` لإنشاء غلاف كائن لنوع بيانات منطقي (Boolean). مع ذلك، لا يُرجع عامل التشغيل `typeof` قيمة منطقية (boolean) لغلاف الكائن، بل يُرجع كائنًا (object ). ولأن جميع الكائنات تُقيّم على أنها صحيحة (true )، يجب استخدام دالة مثل `valueOf()` أو `toString() ` لاسترجاع القيمة المُغلّفة. وللتحويل الصريح إلى النوع المنطقي (Boolean)، توصي موزيلا باستخدام الدالة `Boolean()` (بدون ` new` ) بدلاً من الكائن المنطقي (Boolean).
const b = new Boolean ( false ); // كائن false {} const t = Boolean ( b ); // قيمة منطقية true const f = Boolean ( b.valueOf ( )); // قيمة منطقية false let n = new Boolean ( b ); // غير مُستحسن n = new Boolean ( b.valueOf ( ) ); // مُفضّلإذا كان ( 0 || -0 || "" || null || undefined || b.valueOf () || ! new Boolean () || ! t ) { console.log ( " Never this" ) ; } else if ( [] && { } && b && typeof b === " object" && b.toString () === "false" ) { console.log ( " Always this " ) ; }رمز
الرموز هي ميزة تم تقديمها في ES6 . كل رمز مضمون أن يكون قيمة فريدة، ويمكن استخدامها للتغليف . [ 15 ]
مثال:
let x = Symbol ( 1 ); const y = Symbol ( 1 ); x === y ; // => falseconst symbolObject = {}; const normalObject = {};// بما أن x و y فريدان، // يمكن استخدامهما كمفاتيح فريدة في كائن symbolObject [ x ] = 1 ; symbolObject [ y ] = 2 ;symbolObject [ x ]; // => 1 symbolObject [ y ]; // => 2// بالمقارنة مع المفاتيح الرقمية العادية normalObject [ 1 ] = 1 ; normalObject [ 1 ] = 2 ; // يتجاوز القيمة 1normalObject [ 1 ]; // => 2// تغيير قيمة x لا يُغيّر المفتاح المُخزّن في الكائن x = Symbol ( 3 ); symbolObject [ x ]; // => غير مُعرّف// تغيير قيمة x مرة أخرى يُنشئ رمزًا فريدًا آخر: Symbol x = Symbol ( 1 ); symbolObject [ x ]; // => غير مُعرَّفوهناك أيضاً رموز معروفة جيداً .
أحدها هو Symbol.iterator؛ إذا كان شيء ما ينفذ Symbol.iterator، فإنه قابل للتكرار:
const x = [ 1 , 2 , 3 , 4 ] ; // x عبارة عن مصفوفة x [ Symbol.iterator ] === Array.prototype [ Symbol.iterator ] ; // والمصفوفات قابلة للتكرارconst xIterator = x [ Symbol.iterator ](); // يجب أن توفر الدالة [ Symbol.iterator ] مُكرِّرًا لـ x xIterator.next ( ) ; // { value: 1, done: false } xIterator.next ( ) ; // { value : 2, done: false } xIterator.next ( ); // { value: 3, done: false } xIterator.next ( ); // { value : 4, done: false } xIterator.next ( ); // { value: undefined, done: true } xIterator.next (); // { value: undefined, done: true }// حلقات for..of تُكرر القيم تلقائيًا for ( const value of x ) { console . log ( value ); // 1 2 3 4 }// المجموعات قابلة للتكرار أيضًا : [ Symbol.iterator ] in Set.prototype ; // صحيحfor ( const value of new Set ([ 'apple' , 'orange' ])) { console . log ( value ); // "apple" "orange" }الكائنات الأصلية
توفر لغة جافا سكريبت مجموعة من الكائنات الأصلية . تُعتبر هذه الكائنات جزءًا من مواصفات جافا سكريبت. وبغض النظر عن بيئة جافا سكريبت، يجب أن تكون هذه المجموعة من الكائنات متاحة دائمًا.
المصفوفة
المصفوفة هي كائن جافا سكريبت يتم إنشاؤه من الدالة البانية ،Array وهو مصمم خصيصًا لتخزين قيم البيانات المفهرسة بواسطة مفاتيح عددية صحيحة. على عكس نوع الكائن الأساسي، يتم إنشاء المصفوفات باستخدام طرق وخصائص لمساعدة المبرمج في المهام الروتينية (على سبيل المثال، joinو sliceو و push).
كما هو الحال في عائلة C ، تستخدم المصفوفات نظام فهرسة يبدأ من الصفر: القيمة التي يتم إدخالها في مصفوفة فارغة عن طريق pushالطريقة تشغل الفهرس 0 من المصفوفة.
const myArray = []; // عرّف المتغير myArray كمصفوفة فارغة تم إنشاؤها حديثًا... // ... myArray.push ( "hello World" ); // املأ العنصر التالي في المصفوفة، وهو العنصر الموجود في الفهرس الفارغ التالي، في هذه الحالة 0 console.log ( myArray [ 0 ] ) ; // يُعادل console.log("hello World");تحتوي المصفوفات على lengthخاصية مضمونة بأن تكون دائمًا أكبر من أكبر فهرس صحيح مستخدم في المصفوفة. ويتم تحديثها تلقائيًا عند إنشاء خاصية بفهرس أكبر. كتابة رقم أصغر في lengthالخاصية سيؤدي إلى حذف الفهارس الأكبر.
Arrayيمكن الوصول إلى عناصر s باستخدام تدوين الوصول إلى خصائص الكائنات العادي:
myArray [ 1 ]; // العنصر الثاني في myArray myArray [ "1" ];الخياران المذكوران أعلاه متكافئان. لا يمكن استخدام رمز النقطة أو السلاسل النصية التي تحتوي على تمثيلات بديلة للرقم.
myArray.1 ; // خطأ في بناء الجملة myArray [ "01" ]; // ليس هو نفسه myArray[1]يمكن تعريف المصفوفة إما باستخدام Arrayقيمة حرفية أو Arrayباستخدام الدالة البانية:
let myArray ;// مصفوفة حرفية myArray = [ 1 , 2 ]; // طولها 2 myArray = [ 1 , 2 ]; // نفس المصفوفة - يمكن للمستخدمين أيضًا إضافة فاصلة في النهاية// من الممكن أيضًا عدم ملء أجزاء من المصفوفة myArray = [ 0 , 1 , /* hole */ , /* hole */ , 4 , 5 ]; // طولها 6 myArray = [ 0 , 1 , /* hole */ , /* hole */ , 4 , 5 ,]; // نفس المصفوفة myArray = [ 0 , 1 , /* hole */ , /* hole */ , 4 , 5 , /* hole */ ,]; // طولها 7// باستخدام الدالة البانية myArray = new Array ( 0 , 1 , 2 , 3 , 4 , 5 ); // طولها 6 عناصر myArray = new Array ( 365 ); // مصفوفة فارغة طولها 365 عنصرًاتُنفَّذ المصفوفات بحيث لا تستخدم الذاكرة إلا العناصر المُعرَّفة؛ فهي تُسمى " مصفوفات متفرقة ". يؤدي تعيين ` <T> ` إلى استخدام مساحة لهذين العنصرين فقط، تمامًا مثل أي كائن آخر. سيظل طول المصفوفة يُبلغ عنه كـ 58. يبلغ الحد الأقصى لطول المصفوفة 4,294,967,295، وهو ما يُعادل العدد الثنائي 32 بت (1111111111111111111111111111111111) 2 .myArray[10]='someThing'myArray[57]='somethingOther'length
يمكن استخدام تعريف الكائن الحرفي لإنشاء كائنات تتصرف بشكل مشابه للمصفوفات الترابطية في لغات البرمجة الأخرى:
const dog = { color : "brown" , size : "large" }; dog [ "color" ]; // ينتج عنه "brown" dog . color ; // ينتج عنه أيضًا "brown"يمكن استخدام تعريفات الكائنات والمصفوفات لإنشاء مصفوفات ترابطية أو متعددة الأبعاد أو كليهما بسرعة. (من الناحية التقنية، لا تدعم جافا سكريبت المصفوفات متعددة الأبعاد، ولكن يمكن محاكاتها باستخدام مصفوفات المصفوفات).
const cats = [{ color : "brown" , size : "large" }, { color : "black" , size : "small" }]; cats [ 0 ][ "size" ]; // النتيجة هي "large"const dogs = { rover : { color : "brown" , size : "large" }, spot : { color : "black" , size : "small" }}; dogs [ "spot" ][ "size" ]; // النتيجة "small" dogs . rover . color ; // النتيجة "brown"تاريخ
يخزن الكائن Dateعددًا بالمللي ثانية، حيث يمثل الصفر تاريخ 1970-01-01 00:00:00 بالتوقيت العالمي، ضمن نطاق ±10⁸ يومًا . توجد عدة طرق لتمرير الوسائط إلى Dateالدالة البانية. لاحظ أن الأشهر تبدأ من الصفر.
new Date (); // إنشاء كائن تاريخ جديد يمثل التاريخ/الوقت الحالي. new Date ( 2010 , 2 , 1 ); // إنشاء كائن تاريخ جديد يمثل 2010-مارس-01 00:00:00 new Date ( 2010 , 2 , 1 , 14 , 25 , 30 ); // إنشاء كائن تاريخ جديد يمثل 2010-مارس-01 14:25:30 new Date ( "2010-3-1 14:25:30" ); // إنشاء كائن تاريخ جديد من سلسلة نصية.تتوفر طرق لاستخراج الحقول، بالإضافة إلى ما يلي toString:
const d = new Date ( 2010 , 2 , 1 , 14 , 25 , 30 ); // 2010-مارس-01 14:25:30;// يعرض ' 2010-3-1 14:25:30': console.log(d.getFullYear ( ) + ' - ' + ( d.getMonth ( ) + 1 ) + ' - ' + d.getDate ( ) + ' ' + d.getHours ( ) + ' : ' + d.getMinutes ( ) + ' : ' + d.getSeconds ( ) );// تُرجع الدالة toString المدمجة شيئًا مثل 'Mon 1 March, 2010 14:25:30 GMT-0500 (EST)': console.log ( d ) ;خطأ
يمكن إنشاء رسائل خطأ مخصصة باستخدام Errorالفئة:
throw new Error ( “حدث خطأ ما.” );يمكن التقاط هذه الأخطاء باستخدام كتل try...catch...finally كما هو موضح في قسم معالجة الاستثناءات .
الرياضيات
يحتوي كائن Math على ثوابت رياضية متنوعة (مثل π ) ودوال (مثل جيب التمام). (لاحظ أن كائن Math لا يحتوي على مُنشئ، على عكس Array أو Date . جميع توابعه "ثابتة"، أي توابع "خاصة بالفئة"). تستخدم جميع الدوال المثلثية الزوايا المُعبر عنها بالراديان ، وليس بالدرجات أو الغراد .
| ملكية | القيمة المُعادة مُقرّبة إلى 5 أرقام | وصف |
|---|---|---|
| الرياضيات هـ | 2.7183 | e : أساس اللوغاريتم الطبيعي |
| Math.LN2 | 0.69315 | اللوغاريتم الطبيعي للعدد 2 |
| Math.LN10 | 2.3026 | اللوغاريتم الطبيعي للعدد 10 |
| Math.LOG2E | 1.4427 | اللوغاريتم ذو الأساس 2 للعدد e |
| Math.LOG10E | 0.43429 | اللوغاريتم العشري لـ e |
| Math.PI | 3.14159 | π : محيط/قطر الدائرة |
| Math.SQRT1_2 | 0.70711 | الجذر التربيعي لـ ½ |
| Math.SQRT2 | 1.4142 | الجذر التربيعي لـ 2 |
| مثال | القيمة المُعادة مُقرّبة إلى 5 أرقام | وصف |
|---|---|---|
| Math.abs(-2.3) | 2.3 | القيمة المطلقة |
| Math.acos(Math.SQRT1_2) | 0.78540 راديان = 45 درجة | جيب الزاوية العكسي |
| Math.asin(Math.SQRT1_2) | 0.78540 راديان = 45 درجة | جيب الزاوية العكسي |
| Math.atan(1) | 0.78540 راديان = 45 درجة | ظل الزاوية العكسي لنصف الدائرة ( إلى) |
| Math.atan2(-3.7, -3.7) | -2.3562 راديان =-135 درجة | دالة الظل العكسي للدائرة الكاملة ( إلى) |
| Math.ceil(1.1) | 2 | السقف: التقريب إلى أصغر عدد صحيح ≥ الوسيط |
| Math.cos(Math.PI/4) | 0.70711 | جيب التمام |
| Math.exp(1) | 2.7183 | الدالة الأسية : e مرفوعة إلى هذا الأس |
| Math.floor(1.9) | 1 | التقريب إلى أقرب عدد صحيح أصغر من أو يساوي القيمة المُدخلة. |
| Math.log(Math.E) | 1 | اللوغاريتم الطبيعي، أساسه e |
| Math.max(1, -2) | 1 | الحد الأقصى: (س > ص) ؟ س : ص |
| Math.min(1, -2) | -2 | الحد الأدنى: (س < ص) ؟ س : ص |
| Math.pow(-3, 2) | 9 | الأسس (مرفوعة إلى قوة): Math.pow(x, y) تعطي x y |
| Math.random() | مثال: 0.17068 | رقم شبه عشوائي بين 0 (شامل) و1 (غير شامل) |
| Math.round(1.5) | 2 | قرّب إلى أقرب عدد صحيح؛ يتم تقريب الكسور النصفية إلى الأعلى (على سبيل المثال، 1.5 يتم تقريبها إلى 2). |
| Math.sin(Math.PI/4) | 0.70711 | جيب |
| Math.sqrt(49) | 7 | الجذر التربيعي |
| Math.tan(Math.PI/4) | 1 | مماس |
التعبير النمطي
/expression/ . test ( string ); // تُرجع قيمة منطقية "string" . search ( /expression/ ); // تُرجع رقم الموضع "string" . replace ( /expression/ , replacement );// إليك بعض الأمثلة إذا ( /Tom/ . test ( "My name is Tom" )) console . log ( "Hello Tom!" ); console . log ( "My name is Tom" . search ( /Tom/ )); // == 11 (الأحرف التي تسبق Tom) console . log ( "My name is Tom" . replace ( /Tom/ , "John" )); // == "My name is John"فئات الشخصيات
// \d - رقم // \D - ليس رقمًا // \s - مسافة // \S - ليس مسافة // \w - حرف كلمة // \W - ليس كلمة // [ ] - واحد من // [^] - ليس من // - - نطاقإذا كان الحرف ` /\d/` يحتوي على ` ' 0'` ، فسيتم تسجيله في وحدة التحكم . إذا كان الحرف ` /[0-9]/` يحتوي على ` '6'` ، فسيتم تسجيله في وحدة التحكم . إذا كان الحرف ` /[13579]/` يحتوي على ` ' 1'` ، فسيتم تسجيله في وحدة التحكم . إذا كان الحرف `/\S\S\S\S\S\S/` يحتوي على `'My name'` ، فسيتم تسجيله في وحدة التحكم . إذا كان التنسيق صحيحًا، فسيتم تسجيله في وحدة التحكم. إذا كان الحرف ` /\w\w\w/ ` يحتوي على `'Tom'` ، فسيتم تسجيله في وحدة التحكم . إذا كان الحرف ` /[a-zA-Z]/ ` يحتوي على ` ' B'` ، فسيتم تسجيله في وحدة التحكم .مطابقة الأحرف
// A...Z a...z 0...9 - أبجدي رقمي // \u0000...\uFFFF - يونيكود سداسي عشري // \x00...\xFF - ASCII سداسي عشري // \t - علامة جدولة // \n - سطر جديد // \r - CR // . - أي حرف // | - أوإذا كان ( /Tm/ . test ( 'Tom' )) console . log ( 'مرحباً توم، تام أو تيم' ); إذا كان ( /A|B/ . test ( "A" )) console . log ( 'A أو B' );أجهزة إعادة الإرسال
// ؟ - تطابق 0 أو 1 // * - 0 أو أكثر // + - 1 أو أكثر // {n} - n بالضبط // {n,} - n أو أكثر // {0,n} - n أو أقل // {n,m} - النطاق من n إلى mإذا كانت نتيجة اختبار ` /ab?c/` هي "ac" ، فسيتم تسجيل " OK" في وحدة التحكم . // التطابق: "ac"، "abc" إذا كانت نتيجة اختبار ` /ab*c/` هي "ac" ، فسيتم تسجيل " OK" في وحدة التحكم . // التطابق: "ac"، "abc"، "abbc"، "abbbc" إلخ. إذا كانت نتيجة اختبار ` /ab+c/` هي " abc" ، فسيتم تسجيل "OK" في وحدة التحكم . // التطابق: "abc"، "abbc"، "abbbc" إلخ. إذا كانت نتيجة اختبار ` /ab{3}c/` هي "abbbc" ، فسيتم تسجيل "OK" في وحدة التحكم . // التطابق : "abbbc" إذا كانت نتيجة اختبار ` /ab{3,}c/` هي " abbbc" ، فسيتم تسجيل "OK" في وحدة التحكم . // التطابق: "abbbc"، "abbbbc"، "abbbbbc" إلخ. إذا كانت نتيجة اختبار ` /ab{1,3}c/` هي " abc" ، فسيتم تسجيل " OK" في وحدة التحكم . سجل ( "موافق" )؛ // تطابق: "abc"، "abbc"، "abbbc"المراسي
// ^ - سلسلة تبدأ بـ // $ - سلسلة تنتهي بـإذا كان اسمي توم ، فسيتم طباعة " مرحباً !" في وحدة التحكم . وإذا كان اسمي توم، فسيتم طباعة " مرحباً توم ! " في وحدة التحكم .التعبير الفرعي
// ( ) - مجموعات الأحرفإذا كانت علامة الماء موجودة في النص، فسيتم تسجيل رسالة " هنا ماء ! " في وحدة التحكم . وإذا كانت علامة الماء موجودة في النص، فسيتم تسجيل رسالة " مرحباً توم أو جون ! " في وحدة التحكم .الأعلام
// /g - عام // /i - تجاهل الأحرف الكبيرة/الصغيرة // /m - السماح للمطابقات بالامتداد على عدة أسطرconsole.log ( "hi tom!" . replace ( "Tom/i" , "John" )); // == "hi John!" console.log ( " ratatam " .replace ( " ta/" , " tu " )); // == "ratutam" console.log ( "ratatam" .replace ( " ta/g" , " tu " )); // == "ratutum"أساليب متقدمة
my_array = my_string.split ( my_delimiter ) ; // مثال my_array = "dog,cat,cow" .split ( "," ) ; // my_array==["dog","cat","cow"] ;my_array = my_string.match ( my_expression ); // مثال my_array = "We start at 11:30, 12:15 and 16:45" .match ( / \d\d:\d\d/g ) ; // my_array==["11:30","12:15","16:45"];مجموعات الاستحواذ
const myRe = /(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})/ ; const results = myRe . exec ( "التاريخ والوقت هما 2009-09-08 09:37:08." ); if ( results ) { console . log ( "تمت المطابقة: " + results [ 0 ]); // المطابقة الكاملة const my_date = results [ 1 ]; // المجموعة الأولى == "2009-09-08" const my_time = results [ 2 ]; // المجموعة الثانية == "09:37:08" console . log ( `الوقت هو ${ my_time } في ${ my_date } ` ); } else console . log ( "لم يتم العثور على تاريخ صالح!" );وظيفة
كل دالة في جافا سكريبت هي نسخة من Functionالدالة البانية :
// x و y هما الوسيطان. 'return x + y' هو جسم الدالة، وهو الأخير في قائمة الوسائط. const add = new Function ( 'x' , 'y' , 'return x + y' ); add ( 1 , 2 ); // => 3يمكن أيضًا تعريف دالة الجمع المذكورة أعلاه باستخدام تعبير دالة:
const add = function ( x , y ) { return x + y ; }; add ( 1 , 2 ); // => 3في ES6، أُضيفت صيغة الدوال السهمية، مما يسمح للدوال التي تُرجع قيمة بأن تكون أكثر اختصارًا. كما أنها تحتفظ بخاصية thisالكائن العام بدلًا من وراثتها من مكان استدعائها/ما تم استدعاؤها عليه، على عكس function() {}التعبير.
const add = ( x , y ) => { return x + y ;}; // يمكن أيضًا إرجاع القيم ضمنيًا (أي لا حاجة لعبارة return) const addImplicit = ( x , y ) => x + y ;أضف ( 1 ، 2 )؛ // => 3 أضف ضمنيًا ( 1 ، 2 ) // => 3بالنسبة للوظائف التي تحتاج إلى رفعها، يوجد تعبير منفصل:
دالة الجمع ( س ، ص ) { تُرجع س + ص ؛ } الجمع ( 1 ، 2 )؛ // => 3تتيح خاصية الرفع للمستخدمين استخدام الوظيفة قبل "إعلانها":
add ( 1 , 2 ); // => 3، ليس خطأ مرجعي. الدالة add ( x , y ) { return x + y ; }يحتوي مثيل الدالة على خصائص وأساليب.
دالة طرح ( س ، ص ) { إرجاع س - ص ؛ }console.log ( subtract.length ) ; // = > 2 ، عدد الوسائط في الدالة console.log ( subtract.toString ( ) ) ;/* "function subtract(x, y) { return x - y; }" */المشغلون
يُستخدم عامل الجمع (+) لأغراض متعددة : فهو يُستخدم لدمج السلاسل النصية والجمع الحسابي. قد يُسبب هذا مشاكل عند الخلط غير المقصود بين السلاسل النصية والأرقام. وبصفته عاملًا أحاديًا، يُمكنه تحويل سلسلة نصية رقمية إلى رقم.
// دمج سلسلتين نصيتين console.log ( ' He' + 'llo' ); // يعرض Hello// اجمع عددين console.log ( 2 + 6 ); // يعرض 8// إضافة رقم وسلسلة نصية ينتج عنها دمج (من اليسار إلى اليمين) console.log ( 2 + ' 2 ' ) ; // يعرض 22 console.log ( '$' + 3 + 4 ) ; // يعرض 34$، ولكن ربما كان من المتوقع 7$ console.log ( ' $' + ( 3 + 4 )); // يعرض 7$ console.log ( 3 + 4 + '7' ); // يعرض 77، وتبقى الأرقام أرقامًا حتى تتم إضافة سلسلة نصية// تحويل سلسلة نصية إلى رقم باستخدام عامل الجمع الأحادي console.log ( ' 2' === 2 ); // يعرض القيمة true console.log ( ' Hello' ) ; // يعرض NaNوبالمثل، فإن عامل التشغيل '*' مُحمّل بشكل زائد: إذ يمكنه تحويل سلسلة نصية إلى رقم.
console.log ( 2 + ' 6 ' * 1 ); // يعرض 8 console.log ( 3 * '7' ); // يعرض 21 console.log ( '3' * '7'); // يعرض 21 console.log ( ' hello ' * ' world ' ) ; // يعرض NaNالحساب
يدعم جافا سكريبت عوامل التشغيل الحسابية الثنائية التالية :
+ | إضافة |
- | الطرح |
* | الضرب |
/ | القسمة (تعيد قيمة عددية عشرية) |
% | باقي القسمة (يعيد الباقي) |
** | الأس |
يدعم جافا سكريبت عوامل التشغيل الحسابية الأحادية التالية :
+ | التحويل الأحادي للسلسلة إلى رقم |
- | النفي الأحادي (يعكس الإشارة) |
++ | الزيادة (يمكن أن تكون بادئة أو لاحقة) |
-- | التناقص (يمكن أن يكون بادئة أو لاحقة) |
let x = 1 ; console.log ( ++ x ); // x تصبح 2؛ يعرض 2 console.log ( x ++ ) ; // يعرض 2 ؛ x تصبح 3 console.log ( x ); // x هي 3 ؛ يعرض 3 console.log ( x- ) ; // يعرض 3؛ x تصبح 2 console.log ( x ) ; // يعرض 2 ؛ x هي 2 console.log ( -x ) ; // x تصبح 1؛ يعرض 1يعرض عامل باقي القسمة (modulo) الباقي بعد القسمة على باقي القسمة. في حالة الأعداد السالبة، تعتمد القيمة المُعادة على العدد المُقاس.
const x = 17 ; console.log ( x % 5 ) ; // يعرض 2 console.log ( x % 6 ) ; // يعرض 5 console.log ( -x % 5 ) ; // يعرض -2 console.log ( -x % -5 ) ; // يعرض -2 console.log ( x % -5 ) ; // يعرض 2للحصول على نتيجة غير سالبة دائمًا، يمكن للمستخدمين إعادة جمع باقي القسمة وتطبيق عامل باقي القسمة مرة أخرى:
const x = 17 ; console.log ( ( - x % 5 + 5 ) % 5 ); // يعرض 3ويمكن للمستخدمين أيضاً القيام بما يلي:
const x = 17 ; console.log ( Math.abs ( -x % 5 ) ) ; // أيضًا 3تكليف
= | تعيين |
+= | أضف وعيّن |
-= | اطرح وخصص |
*= | اضرب وخصص |
/= | قسّم ووزّع |
%= | باقي القسمة والتخصيص |
**= | الأسس والتخصيص |
let x = 9 ; x += 1 ; console.log ( x ); // يعرض : 10 x *= 30 ; console.log ( x ); // يعرض : 300 x /= 6 ; console.log ( x ); // يعرض : 50 x - = 3 ; console.log ( x ) ; // يعرض: 47 x %= 7 ; console.log ( x ) ; // يعرض : 5تحديد أنواع الكائنات
/** * لتعلم كائنات جافا سكريبت... */ const object_1 = { a : 1 }; // تعيين مرجع الكائن المُنشأ حديثًا إلى object_1 let object_2 = { a : 0 }; let object_3 = object_2 ; // يشير object_3 إلى نفس الكائن الذي يشير إليه object_2 object_3 . a = 2 ; message ( ); // يعرض 1 2 2 object_2 = object_1 ; // يشير object_2 الآن إلى نفس الكائن الذي يشير إليه object_1 // لا يزال object_3 يشير إلى ما كان يشير إليه object_2 سابقًا message (); // يعرض 1 1 2 object_2 . a = 7 ; // يُعدّل object_1 message (); // يعرض 7 7 2object_3.a = 5 ; // لا يُغيّر object_3 قيمة object_2 message ( ); // يعرض 7 7 5object_3 = object_2 ; object_3.a = 4 ; // يُغيّر object_3 قيمة object_1 و object_2 message ( ) ; // يعرض 4 4 4/** * يطبع رسالة console.log */ function message () { console . log ( object_1 . a + " " + object_2 . a + " " + object_3 . a ); }مهمة تفكيك الهيكل
في جافا سكريبت من موزيلا، منذ الإصدار 1.7، تسمح عملية التفكيك بتعيين أجزاء من هياكل البيانات إلى عدة متغيرات في آن واحد. يُمثل الجانب الأيسر من عملية التعيين نمطًا يُشبه كائنًا/مصفوفة حرفية متداخلة بشكل عشوائي، تحتوي على قيم l-lvalues في أوراقها، والتي ستستقبل البنى الفرعية للقيمة المُعينة.
let a , b , c , d , e ; [ a , b , c ] = [ 3 , 4 , 5 ]; console.log ( ` $ { a } , ${ b } , ${ c } ` ); // يعرض : 3,4,5 e = { foo : 5 , bar : 6 , baz : [ 'Baz' , 'Content' ]}; const arr = []; ({ baz : [ arr [ 0 ], arr [ 3 ]], foo : a , bar : b } = e ); console.log ( ` $ { a } , ${ b } , ${ arr } ` ); // يعرض : 5,6,Baz,,,Content [ a , b ] = [ b , a ]; // تبديل محتويات a و b console.log (`${a} , ${b}, ${arr}`) ; log ( a + ',' + b ); // يعرض: 6,5[ a , b , c ] = [ 3 , 4 , 5 ]; // التباديل [ a , b , c ] = [ b , c , a ]; console.log ( ` $ { a } , ${ b } , ${ c } ` ); // يعرض: 4، 5، 3مشغل عمليات النشر/الراحة
قدّم معيار ECMAScript 2015 ...عامل المصفوفة " "، وذلك للدلالة على المفاهيم ذات الصلة "بنية النشر" [ 16 ] و"معاملات الباقي". [ 17 ] أُضيف نشر الكائنات في ECMAScript 2018.
توفر صيغة التوزيع طريقة أخرى لتفكيك المصفوفات والكائنات. بالنسبة للمصفوفات، تشير إلى أنه يجب استخدام العناصر كمعاملات في استدعاء دالة أو كعناصر في مصفوفة حرفية. أما بالنسبة للكائنات، فيمكن استخدامها لدمج الكائنات معًا أو لتجاوز خصائصها.
بمعنى آخر، " ..." يحول " [...foo]" إلى " [foo[0], foo[1], foo[2]]"، و " this.bar(...foo);" إلى " this.bar(foo[0], foo[1], foo[2]);"، و " { ...bar }" إلى { prop: bar.prop, prop2: bar.prop2 }.
const a = [ 1 , 2 , 3 , 4 ];// يمكن استخدامه عدة مرات في نفس التعبيرconst b = [... a , ... a ]; // b = [1, 2, 3, 4, 1, 2, 3, 4];// يمكن دمجها مع العناصر غير الموزعة.const c = [ 5 , 6 , ... a , 7 , 9 ]; // c = [5, 6, 1, 2, 3, 4, 7, 9];// للمقارنة، قم بذلك بدون عامل النشر// يُنشئ مصفوفة متداخلة.const d = [ a , a ]; // d = [[1, 2, 3, 4], [1, 2, 3, 4]]// يعمل الأمر بنفس الطريقة مع استدعاءات الدوالدالة foo ( arg1 , arg2 , arg3 ) {console.log ( ` ${ arg1 } : ${ arg2 } : $ { arg3 } ` ) ;}// يمكن للمستخدمين استخدامه حتى لو مرر معلمات أكثر مما ستستخدمه الدالةفو (... أ )؛ // "1:2:3" → foo(a[0], a[1], a[2], a[3]);// يمكن للمستخدمين مزجه مع معلمات غير منتشرةفو ( 5 , ... أ , 6 ); // "5:1:2" → foo(5, a[0], a[1], a[2], a[3], 6);// للمقارنة، قم بذلك بدون عامل النشر// يقوم بتعيين المصفوفة إلى arg1، ولا يقوم بتعيين أي شيء للمعاملات الأخرى.foo ( a ); // "1,2,3,4:undefined:undefined"const bar = { a : 1 , b : 2 , c : 3 };// سيؤدي هذا إلى نسخ الكائنconst copy = { ... bar }; // copy = { a: 1, b: 2, c: 3 };سيتم تجاوز "b" هناconst override = { ... bar , b : 4 }; // override = { a: 1, c: 3, b: 4 }عند ...استخدام ` restatement` في تعريف دالة ، فإنه يشير إلى مُعامل مُتبقٍ . يجب أن يكون هذا المُعامل هو آخر مُعامل مُسمى في قائمة مُعاملات الدالة. سيتم تخصيص مُعامل له Arrayيحتوي على أي وسائط مُمررة إلى الدالة تتجاوز الوسائط المُسماة الأخرى. بعبارة أخرى، يحصل على "باقي" الوسائط المُمررة إلى الدالة (ومن هنا جاءت التسمية).
دالة foo ( a , b , ... c ) { console . log ( c . length ); }foo ( 1 , 2 , 3 , 4 , 5 ); // "3" → c = [3, 4, 5] foo ( 'a' , 'b' ); // "0" → c = []تُشبه معاملات الراحة argumentsكائن جافا سكريبت، وهو كائن شبيه بالمصفوفة يحتوي على جميع المعاملات (المسماة وغير المسماة) في استدعاء الدالة الحالي. argumentsولكن على عكس ذلك، فإن معاملات الراحة هي Arrayكائنات حقيقية، لذا يمكن استخدام طرق مثل .slice()و .sort()عليها مباشرةً.
مقارنة
== | متساوي |
!= | غير متساوين |
> | أكبر من |
>= | أكبر من أو يساوي |
< | أقل من |
<= | أقل من أو يساوي |
=== | متطابق (متساوي ومن نفس النوع) |
!== | غير متطابقين |
تكون المتغيرات التي تشير إلى الكائنات متساوية أو متطابقة فقط إذا كانت تشير إلى نفس الكائن:
const obj1 = { a : 1 }; const obj2 = { a : 1 }; const obj3 = obj1 ; console . log ( obj1 == obj2 ); //false console . log ( obj3 == obj1 ); //true console . log ( obj3 === obj1 ); //trueانظر أيضًا إلى السلسلة .
منطقي
توفر لغة جافا سكريبت أربعة عوامل منطقية:
- النفي الأحادي (
NOT = !a) - الفصل الثنائي (
OR = a || b) والوصل الثنائي (AND = a && b) - الشرط الثلاثي ( )
c ? t : f
في سياق عملية منطقية، يكون تقييم أي تعبير صحيحًا باستثناء ما يلي :
- السلاسل:
""،''، - الأرقام:
0،-0،NaN، - خاص:
null،undefined، - منطقي:
false.
يمكن استخدام الدالة المنطقية للتحويل صراحةً إلى نوع بدائي من النوع Boolean:
// تُرجع السلاسل الفارغة فقط القيمة false . console.log(Boolean ( " " ) === false ) ; console.log ( Boolean ( " false " ) === true ) ; console.log ( Boolean ( " 0" ) === true ) ;// فقط الصفر و NaN تُرجعان خطأ console.log ( Boolean ( NaN ) === false ) ; console.log ( Boolean ( 0 ) === false ) ; console.log ( Boolean ( -0 ) === false ) ; // يُعادل -1 * 0 console.log ( Boolean ( -2 ) === true ) ;// جميع الكائنات تُرجع القيمة true console.log ( Boolean ( this ) === true ) ; console.log ( Boolean ( {}) === true ) ; console.log ( Boolean ( []) === true );// تُرجع هذه الأنواع القيمة false console.log ( Boolean ( null ) === false ) ; console.log ( Boolean ( undefined ) === false ); // مكافئ لـ Boolean( )يُقيّم عامل النفي (NOT) مُعامله كقيمة منطقية (Boolean) ويعيد النفي. استخدام هذا العامل مرتين متتاليتين، كنفي مزدوج ، يُحوّل التعبير صراحةً إلى قيمة منطقية (Boolean).
console.log ( ! 0 === Boolean ( ! 0 ) ); console.log ( Boolean ( ! 0 ) === !! 1 ) ; console.log ( !! 1 === Boolean ( 1 ) ) ; console.log ( !! 0 === Boolean ( 0 )); console.log ( Boolean ( 0 ) === ! 1 ) ; console.log ( ! 1 === Boolean ( ! 1 ) ) ; console.log ( ! " " === Boolean ( ! "" ) ) ; console.log ( Boolean ( ! " " ) === !! "s" ) ; console.log ( !! "s" === Boolean ( "" ) ); console.log ( !! "" === Boolean ( " " )); console.log ( Boolean ( " " ) === ! " s " ) ; console.log ( ! " s " === Boolean ( ! " s " ) ) ;يمكن أيضًا استخدام عامل التشغيل الثلاثي للتحويل الصريح:
console.log ([] == false); console.log([] ? true : false); // "trueth"، لكن المقارنة تستخدم [].toString() console.log([0] == false); console.log ( [ 0 ] ? true : false ) ; // [ 0 ] .toString ( ) == " 0 " console.log ( " 0 " == false ) ; console.log ( " 0 " ? true : false ) ; // " 0 " → 0 ... ( 0 == 0 ) ... 0 ← false console.log ([ 1 ] == true ) ; console.log ( [ 1 ] ? true : false ); // [1].toString() == "1" console.log ( " 1 " == true ); console.log ( " 1" ? true : false ); // "1" → 1 ... (1 == 1) ... 1 ← true console . console.log ([ 2 ] != true ) ; console.log ([ 2 ] ? true : false ); // [2].toString() == "2" console.log ( " 2" ! = true ); console.log ( " 2" ? true : false ) ; // "2" → 2 ... (2 != 1) ... 1 ← trueتُسبب التعابير التي تستخدم ميزات مثل الزيادة اللاحقة ( ) أثرًا جانبيًاi++ متوقعًا . يوفر جافا سكريبت تقييمًا مختصرًا للتعابير؛ حيث يتم تنفيذ المعامل الأيمن فقط إذا لم يكن المعامل الأيسر كافيًا لتحديد قيمة التعبير.
console.log ( a || b ); // عندما تكون a صحيحة ، فلا داعي لتقييم b. console.log ( a && b ); // عندما تكون a خاطئة، فلا داعي لتقييم b. console.log(c ? t : f ) ; // عندما تكون c صحيحة ، فلا داعي لتقييم f.في الإصدارات الأولى من جافا سكريبت وجي سكريبت ، كانت عوامل التشغيل المنطقية الثنائية تُرجع قيمة منطقية (مثل معظم لغات البرمجة المشتقة من لغة سي). ومع ذلك، فإن جميع التطبيقات الحديثة تُرجع أحد معاملاتها بدلاً من ذلك.
console.log ( a || b ); // إذا كانت a صحيحة، فأرجع a، وإلا فأرجع b. console.log ( a && b ) ; // إذا كانت a خاطئة، فأرجع a، وإلا فأرجع b .قد يجد المبرمجون الأكثر دراية بسلوك لغة C هذه الميزة مفاجئة، لكنها تسمح بتعبير أكثر إيجازًا عن أنماط مثل دمج القيم الفارغة :
const s = t || "(default)" ; // يُسند قيمة t، أو القيمة الافتراضية، إذا كانت t فارغة أو معدومة، إلخ.التعيين المنطقي
??= | التعيين الصفري |
||= | التعيين المنطقي أو |
&&= | منطقي وتعيين |
بت
يدعم جافا سكريبت عوامل التشغيل الثنائية التالية على مستوى البت :
& | و |
| | أو |
^ | XOR |
! | لا |
<< | إزاحة لليسار (تعبئة صفرية على اليمين) |
>> | إزاحة إلى اليمين (نشر الإشارة)؛ يتم إزاحة نسخ البت الأيسر (بت الإشارة) من اليسار. |
>>> | قم بالإزاحة إلى اليمين (مع ملء الفراغات بالأصفار من اليسار). بالنسبة للأعداد الموجبة، ستحصل على نفس النتيجة.>>>>> |
أمثلة:
const x = 11 & 6 ; console.log ( x ) ; // 2يدعم جافا سكريبت عامل التشغيل الثنائي الأحادي التالي :
~ | لا (يعكس البتات) |
عملية الإسناد الثنائي
يدعم جافا سكريبت عوامل التعيين الثنائية التالية :
&= | و |
|= | أو |
^= | عملية XOR |
<<= | إزاحة لليسار (تعبئة صفرية على اليمين) |
>>= | إزاحة إلى اليمين (نشر الإشارة)؛ يتم إزاحة نسخ البت الأيسر (بت الإشارة) من اليسار. |
>>>= | قم بالإزاحة إلى اليمين (مع ملء الفراغات بالأصفار من اليسار). بالنسبة للأعداد الموجبة، ستحصل على نفس النتيجة.>>=>>>= |
أمثلة:
let x = 7 ; console.log ( x ); // 7 x << = 3 ; console.log ( x ) ; // 7->14- > 28-> 56خيط
= | تكليف |
+ | سلسلة |
+= | قم بدمج البيانات وتعيينها |
أمثلة:
دع str = "ab" + "cd" ؛ // "abcd" str += "e" ; // "اي بي سي دي"const str2 = "2" + 2 ; // "22", وليس "4" أو 4.??
أقرب عامل في جافا سكريبت?? هو عامل دمج القيم الفارغة، الذي أُضيف إلى المعيار في الإصدار الحادي عشر من ECMAScript . [ 18 ] في الإصدارات السابقة، كان يُمكن استخدامه عبر إضافة Babel ، وفي TypeScript . يُقيّم هذا العامل المعامل الأيسر، وإذا لم تكن قيمة النتيجة فارغة ( nullأو فارغة undefined)، فإنه يأخذ تلك القيمة كنتيجة؛ وإلا، فإنه يُقيّم المعامل الأيمن ويأخذ القيمة الناتجة كنتيجة.
في المثال التالي، aسيتم تعيين قيمة لـ إذا لم تكن bقيمة أو ، وإلا فسيتم تعيين 3 لها.bnullundefined
const a = b ?? 3 ;قبل ظهور عامل دمج القيم الفارغة، كان المبرمجون يستخدمون عامل OR المنطقي ( ||). ولكن بينما ??يبحث عامل nullOR تحديدًا عن قيمة خاطئة undefined، ||يبحث عامل OR عن أي قيمة خاطئة : null، undefined، ""، ، 0، NaNوبالطبع، false.
في المثال التالي، aسيتم تعيين القيمة لـ إذا كانت bقيمة صحيحة ، وإلا فسيتم تعيين القيمة 3.b
const a = b || 3 ;هياكل التحكم
العبارات المركبة
يشكل زوج من الأقواس المعقوفة وتسلسل من العبارات المحصورة عبارة مركبة، والتي يمكن استخدامها أينما يمكن استخدام عبارة.{ }
إذا ... وإلا
إذا ( expr ) { //العبارات؛ } وإلا إذا ( expr2 ) { //العبارات؛ } وإلا { //العبارات؛ }عامل الشرط (الثلاثي)
يُنشئ عامل الشرط تعبيرًا يُقيّم إلى أحد تعبيرين بناءً على شرطٍ ما. وهذا يُشبه عبارة "if" التي تختار إحدى عبارتين للتنفيذ بناءً على شرطٍ ما. أي أن عامل الشرط بالنسبة للتعبيرات يُشبه عبارة " if" بالنسبة للعبارات.
const result = condition ? expression : alternative ;هو نفسه:
إذا تحقق الشرط ، فإن النتيجة الثابتة تساوي التعبير ؛ وإلا فإن النتيجة الثابتة تساوي البديل .على عكس عبارة if ، لا يمكن للعامل الشرطي حذف فرع "else".
عبارة التبديل
صيغة عبارة التبديل في جافا سكريبت هي كما يلي:
switch ( expr ) { case SOMEVALUE : // عبارات؛ break ; case ANOTHERVALUE : // عبارات لحالة ANOTHERVALUE || ORANOTHERONE // لا توجد عبارة break، يتم الانتقال إلى الحالة التالية case ORANOTHERONE : // عبارات خاصة بـ ORANOTHERONE (أي !ANOTHERVALUE && ORANOTHER)؛ break ; // ينتهي الأمر هنا. case YETANOTHER : // عبارات؛ break ; default : // عبارات؛ break ; }break;هذا الخيار اختياري، ولكنه ضروري في الغالب، وإلا سيستمر تنفيذ التعليمات البرمجية إلى متن كتلة الحالة التالية. يمكن استخدام هذا السلوك الانتقالي عندما تنطبق نفس مجموعة التعليمات في عدة حالات، مما يُنشئ فعليًا فصلًا بين تلك الحالات.- أضف عبارة break في نهاية الحالة الأخيرة كإجراء احترازي، في حالة إضافة حالات إضافية لاحقًا.
- يمكن أيضًا استخدام القيم النصية الحرفية لقيم الحالة.
- يمكن استخدام التعبيرات بدلاً من القيم.
- يتم تنفيذ الحالة الافتراضية (اختيارية) عندما لا يتطابق التعبير مع أي من الحالات المحددة الأخرى.
- يلزم استخدام تقويم الأسنان.
حلقة تكرارية
صيغة حلقة التكرار for في جافا سكريبت هي كالتالي:
for ( initial ; condition ; loop statement ) { /* سيتم تنفيذ العبارات في كل مرة تدور فيها حلقة for{}، طالما أن الشرط متحقق */ }أو
for ( initial ; condition ; loop statement ( iteration )) // عبارة واحدةfor ... in loop
تكون صيغة جافا سكريبت for ... in loopكما يلي:
for ( var property_name in some_object ) { // عبارات باستخدام some_object[property_name]; }- يتكرر عبر جميع الخصائص القابلة للتعداد لكائن ما.
- تتكرر هذه العملية على جميع عناصر المصفوفة المستخدمة، بما في ذلك جميع خصائص كائن المصفوفة المُعرّفة من قِبل المستخدم، إن وُجدت. لذا، قد يكون من الأفضل استخدام حلقة تكرار تقليدية مع فهرس رقمي عند التكرار على عناصر المصفوفات.
- تختلف متصفحات الويب المختلفة فيما يتعلق بالخصائص التي تُعرض في حلقة التكرار `for...in`. نظريًا، يُتحكم في ذلك بواسطة خاصية حالة داخلية مُعرّفة في معيار ECMAscript تُسمى "DontEnum"، ولكن عمليًا، يُعيد كل متصفح مجموعة خصائص مختلفة قليلًا أثناء الفحص. من المفيد اختبار خاصية معينة باستخدام `for...in` . لذا، قد تؤدي إضافة دالة إلى نموذج المصفوفة باستخدام `for...in` إلى تكرار اسم الدالة في حلقات التكرار.
if(some_object.hasOwnProperty(property_name)){...}Array.prototype.newMethod=function(){...}for ... in
حلقة التكرار
صيغة حلقة while في جافا سكريبت هي كالتالي:
بينما ( الشرط ) { العبارة 1 ؛ العبارة 2 ؛ العبارة 3 ؛ ... }نفّذ ... حلقة التكرار
تكون صيغة جافا سكريبت do ... while loopكما يلي:
نفّذ { العبارة 1 ؛ العبارة 2 ؛ العبارة 3 ؛ ... } طالما ( الشرط )؛مع
تضيف عبارة with جميع خصائص وأساليب الكائن المحدد إلى نطاق الكتلة التالية، مما يسمح بالإشارة إليها كما لو كانت متغيرات محلية.
باستخدام ( المستند ) { const a = getElementById ( 'a' ); const b = getElementById ( 'b' ); const c = getElementById ( 'c' ); };- لاحظ غياب كلمة document. قبل كل استدعاء لدالة getElementById() .
الدلالات مشابهة لعبارة "with" في لغة باسكال .
نظرًا لأن توفر عبارات with يعيق أداء البرنامج ويعتقد أنه يقلل من وضوح الكود (حيث يمكن أن يكون أي متغير معين في الواقع خاصية من عبارة with المحيطة )، فإن هذه العبارة غير مسموح بها في الوضع الصارم .
الملصقات
يدعم جافا سكريبت التسميات المتداخلة في معظم تطبيقاته. يمكن تسمية الحلقات أو الكتل بعبارة break، والحلقات بعبارة continue. على الرغم من gotoأن كلمة محجوزة، إلا أن [ 19 ]goto غير مُطبقة في جافا سكريبت.
loop1 : for ( let a = 0 ; a < 10 ; ++ a ) { if ( a === 4 ) break loop1 ; // يتوقف بعد المحاولة الرابعة console.log ( ' a = ' + a ); loop2 : for ( let b = 0 ; b < 10 ; ++ b ) { if ( b === 3 ) continue loop2 ; // يتم تخطي الرقم 3 if ( b === 6 ) continue loop1 ; // يكمل الحلقة الأولى ، ولا يتم عرض 'finished' console.log ( ' b = ' + b ) ; } // نهاية loop2 console.log ( ' finished' ); } // نهاية loop1 block1 : { console.log ( 'Hello' ) ; // يعرض 'Hello' break block1 ; console.log ( 'World' ) ; // لن نصل إلى هنا أبدًا } goto block1 ; // خطأ في التحليل.الوظائف
الدالة عبارة عن كتلة برمجية تحتوي على قائمة معاملات (قد تكون فارغة) تُعطى عادةً اسمًا. يمكن للدالة استخدام متغيرات محلية. إذا خرج المستخدم من الدالة دون كتابة عبارة إرجاع، فسيتم إرجاع القيمة "غير مُعرّفة" .
دالة gcd ( number1 , number2 ) { إذا ( isNaN ( number1 * number2 )) ارمِ خطأ TypeError ( "الوسائط غير الرقمية غير مسموح بها." ); number1 = Math . round ( number1 ); number2 = Math . round ( number2 ); let difference = number1 - number2 ; إذا ( difference === 0 ) أرجع number1 ; أرجع difference > 0 ? gcd ( number2 , difference ) : gcd ( number1 , - difference ); } console . log ( gcd ( 60 , 40 )); // 20// في حال عدم وجود أقواس بعد المعرّف 'gcd' على الجانب الأيمن من عملية الإسناد أدناه، // تُعيد 'gcd' مرجعًا إلى الدالة نفسها دون استدعائها. let mygcd = gcd ; // يشير كل من mygcd و gcd إلى نفس الدالة. console . log ( mygcd ( 60 , 40 )); // 20تُعتبر الدوال عناصر أساسية ويمكن إسنادها إلى متغيرات أخرى.
قد لا يتطابق عدد الوسائط المُمرَّرة عند استدعاء دالة بالضرورة مع عدد الوسائط في تعريف الدالة؛ فالوسيط المُسمى في التعريف الذي لا يوجد له وسيط مطابق في الاستدعاء ستكون قيمته غير مُعرَّفة (ويمكن تحويلها ضمنيًا إلى خطأ). داخل الدالة، يمكن أيضًا الوصول إلى الوسائط من خلال كائن الوسائط ؛ وهذا يُتيح الوصول إلى جميع الوسائط باستخدام الفهارس (مثلاً )، بما في ذلك تلك التي تتجاوز عدد الوسائط المُسماة. (مع أن قائمة الوسائط تحتوي على خاصية، إلا أنها ليست نسخة من المصفوفة ؛ فهي لا تحتوي على دوال مثل .slice() و .sort() ، إلخ).arguments[0],arguments[1],...arguments[n].length
دالة add7 ( x , y ) { إذا لم يكن y موجودًا { y = 7 ; } console . log ( x + y + arguments . length ) ; }; add7 ( 3 ); // 11 add7 ( 3 , 4 ); // 9تُمرر القيم الأولية (الأرقام، والقيم المنطقية، والسلاسل النصية) بالقيمة نفسها. أما بالنسبة للكائنات، فيتم تمرير مرجع الكائن.
const obj1 = { a : 1 }; const obj2 = { b : 2 }; function foo ( p ) { p = obj2 ; // يتجاهل المعامل الفعلي p . b = arguments [ 1 ]; } foo ( obj1 , 3 ); // لا يؤثر على obj1 إطلاقًا. 3 هو معامل إضافي console . log ( ` ${ obj1 . a } ${ obj2 . b } ` ); // يكتب 1 3يمكن تعريف الدوال داخل دوال أخرى، والوصول إلى متغيرات الدالة الخارجية المحلية. علاوة على ذلك، فهي تُنفذ إغلاقات كاملة من خلال الاحتفاظ بمتغيرات الدالة الخارجية المحلية حتى بعد انتهاء الدالة الخارجية.
let t = "Top" ; let bar , baz ; function foo () { let f = "foo var" ; bar = function () { console . log ( f ) }; baz = function ( x ) { f = x ; }; } foo (); baz ( "baz arg" ); bar (); // "baz arg" (وليس "foo var") على الرغم من أن foo() قد انتهت. console . log ( t ); // Topالدالة المجهولة هي ببساطة دالة بدون اسم، ويمكن كتابتها باستخدام صيغة الدالة أو صيغة السهم. في هذه الأمثلة المتكافئة، تُمرر دالة مجهولة إلى دالة الخريطة وتُطبق على كل عنصر من عناصر المصفوفة. [ 20 ]
[ 1 , 2 , 3 ] .map ( function ( x ) { return x * 2 ;); // تُرجع [2, 4, 6] [ 1 , 2 , 3 ] .map (( x ) => { return x * 2 ;}); // نفس النتيجةتُعرف دالة المولد بوضع علامة * بعد الكلمة المفتاحية function ، وتحتوي على عبارة yield واحدة أو أكثر . وتتمثل وظيفتها في إرجاع قيمة وإيقاف التنفيذ مؤقتًا عند الحالة الحالية. يؤدي تعريف دالة مولد إلى إرجاع مُكرِّر. تستأنف الاستدعاءات اللاحقة لـ iterator.next() التنفيذ حتى عبارة yield التالية . عندما يُرجع المُكرِّر قيمةً دون استخدام عبارة yield، فهذا يعني عدم وجود قيم أخرى، وتُعيَّن خاصية done الخاصة به إلى true . [ 21 ]
باستثناء أجهزة iOS من شركة Apple، لا يتم تطبيق المولدات على المتصفحات الموجودة على الأجهزة المحمولة. [ 22 ]
دالة * مولد () { ينتج "أحمر" ; ينتج "أخضر" ; ينتج "أزرق" ; }let iterator = generator (); let current ;بينما ( الحالي = قيمة المُكرِّر.التالي () ) console.log ( الحالي ) ؛ // يعرض الأحمر، ثم الأخضر ، ثم الأزرق console.log ( تم المُكرِّر.التالي ( ) ) // يعرض صحيحًاAsync/await
لا يُمكن استخدام عامل الانتظار (await) في جافا سكريبت (وتايب سكريبت) إلا من داخل دالة غير متزامنة أو في المستوى الأعلى من وحدة نمطية . إذا كان المُعامل عبارة عن وعد (promise )، فسيستأنف تنفيذ الدالة غير المتزامنة عند تحقق الوعد (إلا إذا رُفض الوعد، وفي هذه الحالة سيُثار خطأ يُمكن معالجته باستخدام معالجة الاستثناءات العادية في جافا سكريبت ). أما إذا لم يكن المُعامل وعدًا، فسيتم إرجاع المُعامل نفسه فورًا. [ 23 ]
توفر العديد من المكتبات كائنات وعد يمكن استخدامها مع await، طالما أنها تتوافق مع مواصفات وعود جافا سكريبت الأصلية. مع ذلك، لم تكن وعود مكتبة jQuery متوافقة مع Promises/A+ حتى إصدار jQuery 3.0. [ 24 ]
فيما يلي مثال (معدل من هذه المقالة [ 25 ] ):
واجهة DBResponse { id : سلسلة نصية ; rev? : سلسلة نصية ; ok? : قيمة منطقية ; }واجهة المستند { _id : سلسلة نصية ; _rev? : سلسلة نصية ; [ key : سلسلة نصية ] : أي ; }واجهة قاعدة البيانات { post ( doc : object ) : Promise < DBResponse > ; get ( id : string ) : Promise < Document > ; }declare const db : Database ;async function createNewDoc ( ) : Promise <Document> { const response : DBResponse = await db.post ( { } ) ; const doc : Document = await db.get ( response.id ) ; return doc ; }async function main () : Promise <void> { try { const doc : Document = await createNewDoc ( ); console.log ( doc ) ; } catch ( err : Error ) { console.error ( " خطأ في إنشاء أو جلب المستند: " , err ) ; } }رئيسي ()؛يتضمن الإصدار 8 من Node.js أداةً تُمكّن من استخدام طرق الاستدعاء القائمة على ردود الاتصال في المكتبة القياسية كوعود. [ 26 ]
أشياء
لتبسيط الأمور، تُقسّم الأنواع عادةً إلى أنواع أولية وكائنات . الكائنات هي كيانات لها هوية (لا تساوي إلا نفسها) وتربط أسماء الخصائص بقيم ("فتحات" في مصطلحات البرمجة القائمة على النماذج الأولية ). يمكن اعتبار الكائنات بمثابة مصفوفات ترابطية أو جداول تجزئة، وغالبًا ما تُنفّذ باستخدام هذه الهياكل البيانية. مع ذلك، تتميز الكائنات بخصائص إضافية، مثل سلسلة النماذج الأولية ، التي لا توجد في المصفوفات الترابطية العادية.
تحتوي لغة جافا سكريبت على عدة أنواع من الكائنات المدمجة، وهي: Array` Boolean<input>` Date، و`< form> Function`، و` <link> Math`، و` <link> Number`، و` <link Object> `. وهناك كائنات أخرى تُسمى "كائنات مضيفة"، لا تُحددها اللغة نفسها، بل بيئة التشغيل. على سبيل المثال، في المتصفح، تنتمي الكائنات المضيفة النموذجية إلى نموذج كائن المستند (DOM) (مثل: `window`، و`form`، و`links`، وما إلى ذلك).RegExpString
إنشاء الكائنات
يمكن إنشاء الكائنات باستخدام دالة إنشاء أو باستخدام قيمة حرفية للكائن. يمكن لدالة الإنشاء استخدام دالة مدمجة في الكائن أو دالة مخصصة. ومن المتعارف عليه أن تُسمى دوال الإنشاء بأسماء تبدأ بحرف كبير.
// الدالة البانية const anObject = new Object ();// كائن حرفي const objectA = {}; const objectA2 = {}; // A != A2، {} تُنشئ كائنات جديدة كنسخ. const objectB = { index1 : 'value 1' , index2 : 'value 2' };// مُنشئ مخصص (انظر أدناه)تتيح القيم الحرفية للكائنات والقيم الحرفية للمصفوفات إنشاء هياكل بيانات مرنة بسهولة:
const myStructure = { name : { first : "Mel" , last : "Smith" }, age : 33 , hobbies : [ "chess" , "jogging" ] };هذا هو الأساس لـ JSON ، وهو عبارة عن تدوين بسيط يستخدم صيغة تشبه صيغة JavaScript لتبادل البيانات.
طُرق
الطريقة هي ببساطة دالة مُسندة إلى اسم خاصية في كائن. على عكس العديد من لغات البرمجة كائنية التوجه، لا يوجد تمييز بين تعريف الدالة وتعريف الطريقة في جافا سكريبت المتعلقة بالكائنات. بل يظهر التمييز أثناء استدعاء الدالة؛ إذ يمكن استدعاء الدالة كطريقة .
عند استدعاء هذه الدالة، يتم تعيين المتغير المحلي القياسي this تلقائيًا إلى نسخة الكائن الموجودة على يسار النقطة " " . (توجد أيضًا دوال call و apply التي يمكنها تعيين this بشكل صريح - بعض الحزم مثل jQuery تقوم بأشياء غير معتادة مع this .)
في المثال أدناه، يُستخدم Foo كدالة إنشاء. لا يوجد شيء مميز في دالة الإنشاء، فهي مجرد دالة عادية تُهيئ كائنًا. عند استخدامها مع الكلمة المفتاحية new ، كما هو معتاد، يتم تعيينها إلى كائن فارغ تم إنشاؤه حديثًا.
لاحظ أنه في المثال أدناه، يقوم Foo ببساطة بتعيين قيم للفتحات، بعضها دوال. وبالتالي، يمكنه تعيين دوال مختلفة لنسخ مختلفة. لا يوجد نموذج أولي في هذا المثال.
function px () { return this . prefix + "X" ; }دالة Foo ( yz ) { this . prefix = "a-" ; if ( yz > 0 ) { this . pyz = function () { return this . prefix + "Y" ; }; } else { this . pyz = function () { return this . prefix + "Z" ; }; } this . m1 = px ; return this ; }const foo1 = new Foo ( 1 ); const foo2 = new Foo ( 0 ); foo2.prefix = " b- " ;console.log ( "foo1/2 " + foo1.pyz ( ) + foo2.pyz ( ) ) ; // foo1/ 2 aY bZfoo1.m3 = px ; // يُسند الدالة نفسها، وليس نتيجتها المُقيمة، أي ليس px() const baz = { " prefix" : " c-" } ; baz.m4 = px ; // لا حاجة إلى مُنشئ لإنشاء كائن.console.log ( "m1/m3/m4 " + foo1.m1 ( ) + foo1.m3 ( ) + baz.m4 ( ) ); // m1 /m3 / m4 aX aX cXfoo1 . m2 (); // يطرح استثناءً، لأن foo1.m2 غير موجود.المُنشئون
تقوم دوال البناء ببساطة بتعيين قيم لمواقع الكائن الذي تم إنشاؤه حديثًا. قد تكون هذه القيم بيانات أو دوال أخرى.
مثال: التلاعب بكائن:
دالة MyObject ( السمة A ، السمة B ) { this . السمة A = السمة A ; this . السمة B = السمة B ; }MyObject.staticC = " blue" ; // دالة MyObject، وليس الكائن console.log ( MyObject.staticC ) ; // blueconst object = new MyObject ( 'red' , 1000 );console.log ( object.attributeA ) ; // أحمر console.log ( object.attributeB ) ; // 1000console.log ( object.staticC ) ; // غير مُعرَّف object.attributeC = new Date ( ) ; // إضافة خاصية جديدةحذف الكائن . السمة ب ؛ // إزالة خاصية من الكائن // لاحظ أنه على عكس لغة C++، فإن الحذف لا يستدعي "مدمرًا"، // ولكنه يزيل خاصية من الكائن.console.log ( object.attributeB ) ; // غير مُعرَّفتتم الإشارة إلى الدالة البانية نفسها في خانة الدالة البانية للنموذج الأولي للكائن . لذا،
دالة Foo () {} // استخدام 'new' يُعيّن خانات النموذج الأولي (على سبيل المثال، // x = new Foo() سيُعيّن النموذج الأولي لـ x إلى Foo.prototype، // وFoo.prototype يحتوي على خانة مُنشئ تُشير إلى Foo). const x = new Foo ( ); // ما سبق يُكافئ تقريبًا const y = {}; y.constructor = Foo ; y.constructor (); // باستثناء x.constructor == y.constructor ; // صحيح x instanceof Foo ; // صحيح y instanceof Foo ; // خطأ // النموذج الأولي لـ y هو Object.prototype، وليس // Foo.prototype، لأنه تم تهيئته باستخدام // {} بدلاً من new Foo. // على الرغم من تعيين Foo إلى خانة مُنشئ y، // إلا أن instanceof يتجاهل ذلك - يتم النظر فقط في خانة مُنشئ النموذج الأولي لـ y .الدوال هي كائنات بحد ذاتها، ويمكن استخدامها لإنتاج تأثير مشابه لـ "الخصائص الثابتة" (باستخدام مصطلحات C++/Java) كما هو موضح أدناه. (يحتوي كائن الدالة أيضًا على prototypeخاصية خاصة، كما هو موضح في قسم "الوراثة" أدناه).
نادراً ما يتم استخدام حذف الكائنات لأن محرك البرمجة النصية سيقوم بجمع الكائنات التي لم تعد تتم الإشارة إليها.
الميراث
يدعم جافا سكريبت التسلسلات الهرمية للوراثة من خلال النماذج الأولية على غرار Self .
في المثال التالي، ترث الفئة المشتقة من الفئة الأساسية . عند إنشاء d كفئة مشتقة ، يتم نسخ مرجع النسخة الأساسية من الفئة الأساسية إلى d.base .
لا تحتوي الدالة Derive على قيمة لـ aBaseFunction ، لذا يتم استرجاعها من aBaseFunction عند الوصول إليها . ويتضح ذلك من خلال تغيير قيمة base.aBaseFunction ، وهو ما ينعكس في قيمة d.aBaseFunction .
تسمح بعض التطبيقات بالوصول إلى النموذج الأولي أو تعيينه بشكل صريح باستخدام خانة __proto__ كما هو موضح أدناه.
دالة Base () { this.anOverride = دالة () { console.log ( "Base::anOverride( ) " ) ; } ;this.aBaseFunction = function () { console.log ( " Base::aBaseFunction() " ) ; } ; }دالة Derived () { this.anOverride = function ( ) { console.log ( "Derived::anOverride() " ) ; } ; }const base = new Base ( ); Derived.prototype = base ; // يجب أن يكون هذا قبل new Derived() Derived.prototype.constructor = Derived ; // مطلوب لجعل ` instanceof` يعملconst d = new Derived (); // ينسخ Derived.prototype إلى خانة النموذج الأولي المخفية لمثيل d. d instanceof Derived ; // صحيح d instanceof Base ; // صحيحbase.aBaseFunction = function () { console.log ( " Base ::aNEWBaseFunction() " ) ; } ;d.anOverride (); // Derived :: anOverride() d.aBaseFunction ( ) ; // Base :: aNEWBaseFunction ( ) console.log ( d.aBaseFunction == Derived.prototype.aBaseFunction ) ; // صحيحconsole.log ( d .__ proto__ == base ); // صحيح في التطبيقات المستندة إلى Mozilla وخطأ في العديد من التطبيقات الأخرى .يوضح ما يلي بوضوح كيف يتم نسخ المراجع إلى النماذج الأولية عند إنشاء مثيل، ولكن التغييرات التي تطرأ على النموذج الأولي يمكن أن تؤثر على جميع المثيلات التي تشير إليه.
دالة m1 () { تُرجع "واحد" ; } دالة m2 () { تُرجع "اثنان" ; } دالة m3 () { تُرجع "ثلاثة" ; }دالة Base () {}Base.prototype.m = m2 ; const bar = new Base ( ); console.log ( " bar.m " + bar.m ( ) ) ; // bar.m Twoدالة Top ( ) { this.m = m3 ; } const t = new Top ( );const foo = new Base ( ); Base.prototype = t ; // لا يوجد تأثير على foo، يتم نسخ *المرجع* إلى t. console.log ( "foo.m " + foo.m ( ) ); // foo.m اثنانconst baz = new Base (); console.log ( " baz.m " + baz.m ( )); // baz.m Threet.m = m1 ; // يؤثر على baz وأي فئات مشتقة أخرى. console.log ( " baz.m1 " + baz.m ( )); // baz.m1 واحدفي الواقع، يتم استخدام العديد من الاختلافات في هذه المواضيع، ويمكن أن يكون ذلك قوياً ومربكاً في آن واحد.
معالجة الاستثناءات
تتضمن لغة جافا سكريبت عبارة try ... catch ... finallyلمعالجة الاستثناءات للتعامل مع أخطاء وقت التشغيل.
try ... catch ... finallyتلتقط هذه العبارة الاستثناءات الناتجة عن خطأ أو عبارة throw. صيغتها كالتالي:
حاول { // عبارات قد تُثار فيها استثناءات } أمسك ( قيمة الخطأ ) { // عبارات تُنفذ في حالة حدوث استثناء } أخيرًا { // عبارات تُنفذ بعد ذلك في كلتا الحالتين }في البداية، تُنفَّذ التعليمات البرمجية داخل كتلة try. إذا حدث استثناء، ينتقل مسار تنفيذ البرنامج النصي فورًا إلى التعليمات البرمجية في كتلة catch، مع إمكانية استخدام الاستثناء كوسيط للخطأ. وإلا، يتم تخطي كتلة catch. يمكن لكتلة catch استخدام throw(errorValue) إذا لم ترغب في معالجة خطأ معين.
في جميع الأحوال، تُنفَّذ التعليمات البرمجية الموجودة في كتلة finally دائمًا. على الرغم من أن الذاكرة تُجمَع تلقائيًا، إلا أنه يمكن استخدام هذه الخاصية لتنظيف الموارد يدويًا (مثل إغلاق الملفات أو الاتصالات).
يمكن حذف إما عبارة catch أو عبارة finally. لكن عبارة catch مطلوبة.
تتيح نسخة موزيلا استخدام عدة عبارات catch، كامتداد لمعيار ECMAScript. وهي تتبع صيغة مشابهة لتلك المستخدمة في جافا :
حاول { العبارة ؛ } أمسك ( هـ إذا كان هـ == "استثناء الاسم غير صالح" ) { العبارة ؛ } أمسك ( هـ إذا كان هـ == "استثناء المعرف غير صالح" ) { العبارة؛ } أمسك ( هـ إذا كان هـ == "استثناء البريد الإلكتروني غير صالح " ) { العبارة ؛ } أمسك ( هـ ) { العبارة ؛ } أخيرًا { العبارة ؛ }في المتصفح، يُستخدم حدث onerror بشكل أكثر شيوعًا لاصطياد الاستثناءات.
onerror = function ( errorValue , url , lineNr ) {...; return true ;};الوظائف والأساليب الأصلية
تقييم (تعبير)
يُقيّم هذا الأسلوب المعامل الأول كتعبير، والذي قد يتضمن عبارات إسناد. ويمكن الإشارة إلى المتغيرات المحلية للدوال من خلال هذا التعبير. ومع ذلك، evalيُمثل هذا الأسلوب خطرًا أمنيًا كبيرًا، إذ يسمح للمهاجم بتنفيذ تعليمات برمجية عشوائية، لذا يُنصح بتجنب استخدامه. [ 27 ]
> ( function foo () { ... var x = 7 ; ... console . log ( "val " + eval ( "x + 2" )); ... })(); val 9 undefinedميزات خاصة بـ TypeScript
تُضيف لغة TypeScript ، وهي مجموعة فرعية من لغة JavaScript طورتها شركة Microsoft ، امتدادات بناء الجملة التالية إلى JavaScript:
- التوقيعات النوعية (التعليقات التوضيحية) والتحقق من النوع في وقت الترجمة
- استنتاج النوع
- واجهات
- أنواع مُعَدَّة
- الأدوية الجنيسة
- مساحات الأسماء
- المجموعات
- إدارة الموارد الصريحة [ 28 ]
من الناحية التركيبية، تُشبه لغة TypeScript إلى حد كبير لغة JScript .NET ، وهي تطبيق آخر من مايكروسوفت لمعيار لغة ECMA-262، والذي أضاف دعمًا للكتابة الثابتة وميزات لغات البرمجة الكائنية الكلاسيكية مثل الفئات والوراثة والواجهات ومساحات الأسماء. ومن بين مصادر الإلهام الأخرى لغتا Java و C# .
التعليقات التوضيحية للأنواع
يوفر TypeScript الكتابة الثابتة من خلال التعليقات التوضيحية للأنواع لتمكين التحقق من الأنواع في وقت الترجمة .
دالة الجمع ( يسار : رقم ، يمين : رقم ) : رقم { إرجاع يسار + يمين ؛ }تُعرَّف الأنواع الأولية باستخدام أحرف صغيرة فقط، مثل number` boolean<T>` bigintو`<T>` و`<T> string`. وتختلف هذه الأنواع عن نظيراتها المُغلَّفة (مثل `<T>` و`<T>` وما إلى ذلك)، والتي لا يمكن إجراء عمليات عليها مباشرةً (لا يمكن جمع `<T>` Numberو` < T>`). يوجد أيضًا نوعان ` <T>` و`<T>` لقيمها الخاصة.BooleanNumbernumberundefinednull
All other non-primitive types are annotated using their class name, such as Error. Arrays can be written in two different ways which are both syntactically the same: the generic-based syntax Array<T> and a shorthand with T[].
Additional built-in data types are tuples, unions, never, unknown, void, and any:
- An array with predefined data types at each index is a tuple, represented as
[type1, type2, ..., typeN]. - A variable that can hold more than one type of data is a union, represented using the logical OR
|symbol (string | number). - The
nevertype is used when a given type should be impossible to create, which is useful for filtering mapped types. - The
unknowntype is used when dealing with data of an unpredictable shape. Unlikeany, anunknown-typed variable will throw compilation errors when attempting to access properties or methods on that variable without first narrowing the type to something known. This type is often used for catching Errors, handling API responses, or user input.[29] - The
voidtype is used to represent the lack of a type, e.g. from a function with noreturnstatement. - A value of type
anysupports the same operations as a value in JavaScript and minimal static type checking is performed,[30] which makes it suitable for weakly or dynamically typed structures. This is generally discouraged practice and should be avoided when possible.[31]
Type annotations can be exported to a separate declarations file to make type information available for TypeScript scripts using types already compiled into JavaScript. Annotations can be declared for an existing JavaScript library, as has been done for Node.js and jQuery.
The TypeScript compiler makes use of type inference when types are not given. For example, the add method in the code above would be inferred as returning a number even if no return type annotation had been provided. This is based on the static types of left and right being numbers, and the compiler's knowledge that the result of adding two numbers is always a number.
If no type can be inferred because of lack of declarations (such as in a JavaScript module without types), then it defaults to the dynamic any type. Additional module types can be provided using a .d.ts declaration file using the declare module "moduleName" syntax.
Declaration files
When a TypeScript script gets compiled, there is an option to generate a declaration file (with the extension .d.ts) that functions as an interface to the components in the compiled JavaScript. In the process, the compiler strips away all function and method bodies and preserves only the signatures of the types that are exported. The resulting declaration file can then be used to describe the exported virtual TypeScript types of a JavaScript library or module when a third-party developer consumes it from TypeScript.
The concept of declaration files is analogous to the concept of header files found in C/C++.
declarenamespaceArithmetics{add(left:number,right:number):number;subtract(left:number,right:number):number;multiply(left:number,right:number):number;divide(left:number,right:number):number;}Type declaration files can be written by hand for existing JavaScript libraries, as has been done for jQuery and Node.js.
Large collections of declaration files for popular JavaScript libraries are hosted on GitHub in DefinitelyTyped.
Generics
TypeScript supports generic programming using a syntax similar to Java.[32] The following is an example of the identity function.[33]
functionidentity<T>(x:T):T{returnx;}Similar to Java generics, it is possible to bound a type parameter:
functionf<Textendsstring>(x:T):void{// ...}functionprop<T,KextendskeyofT>(obj:T,key:K):T[K]{returnobj[key];}Also, like C++, it is possible to have default generics parameters.
functionmakeArray<T=number>(value:T):T[]{return[value];}Classes
TypeScript uses the same annotation style for class methods and fields as for functions and variables respectively. Compared with vanilla JavaScript classes, a TypeScript class can also implement an interface through the implements keyword, use generic parameters similarly to Java, and specify public and private fields.
classPerson{publicname:string;privateage:number;privatesalary:number;constructor(name:string,age:number,salary:number){this.name=name;this.age=age;this.salary=salary;}toString():string{return`${this.name} (${this.age}) (${this.salary})`;}}Union types
Union types are supported in TypeScript.[34] The values are implicitly "tagged" with a type by the language, and may be retrieved using a typeof call for primitive values and an instanceof comparison for complex data types. Types with overlapping usage (e.g. a slice method exists on both strings and arrays, the plus operator works on both strings and numbers) don't need additional narrowing to use these features.
functionsuccessor(n:number|bigint):number|bigint{// types that support the same operations don't need narrowingreturn++n;}functiondependsOnParameter(v:string|string[]|number){// distinct types need narrowingif(vinstanceofArray){// do something}elseif(typeof(v)==="string"){// do something else}else{// has to be a number}}Enumerated types
TypeScript adds an 'enum' data type to JavaScript.
enumCardSuit{Clubs,Diamonds,Hearts,Spades};letc:CardSuit=CardSuit.Diamonds;By default, enums number members starting at 0; this can be overridden by setting the value of the first:
enumCardSuit{Clubs=1,Diamonds,Hearts,Spades};letc:CardSuit=CardSuit.Diamonds;All the values can be set:
enumCardSuit{Clubs=1,Diamonds=2,Hearts=4,Spades=8};letc:CardSuit=CardSuit.Diamonds;TypeScript supports mapping the numeric value to its name. For example, this finds the name of the value 2:
enumCardSuit{Clubs=1,Diamonds,Hearts,Spades};letsuitName:string=CardSuit[2];alert(suitName);Modules and namespaces
TypeScript distinguishes between modules and namespaces, similar to C++ modules. Both features in TypeScript support encapsulation of classes, interfaces, functions and variables into containers. Namespaces (formerly internal modules) use JavaScript immediately-invoked function expressions to encapsulate code, whereas modules (formerly external modules) use existing JavaScript library patterns (CommonJS or ES Modules).[35]
Resource management
Although TypeScript does not have manual memory management, it has resource management similar to using-with-resource blocks in C# or try-with-resources blocks in Java, or C++resource acquisition is initialization, that automatically close resources without need for finally blocks. In TypeScript, to automatically close an object, it must implement a global interface Disposable, and implement a method Symbol.dispose(). This will automatically be called at the end of scope.[28]
import*asfsfrom'fs';classTempFileimplementsDisposable{#path:string;#handle:number;constructor(path:string){this.#path=path;this.#handle=fs.openSync(path,"w+");}write(data:string):void{fs.writeSync(this.#handle,data);}[Symbol.dispose]():void{fs.closeSync(this.#handle);fs.unlinkSync(this.#path);}}exportfunctiondoSomeWork(){usingfile:TempFile=newTempFile(".some_temp_file.txt");if(someCondition()){// do something here}}See also
References
- ↑"JavaScript 1.1 specification". Archived from the original on 26 February 2017. Retrieved 19 April 2006.
- ↑"Chapter 1. Basic JavaScript". speakingjs.com. Archived from the original on 10 February 2022. Retrieved 22 September 2020.
- ↑Flanagan, David (2006). JavaScript: The definitive Guide. O'Reilly Media, Inc. p. 16. ISBN 978-0-596-10199-2.
Omitting semicolons is not a good programming practice; you should get into the habit of inserting them.
- ↑Farias, Bradley. "Hashbang Grammar". GitHub. Retrieved 13 July 2025.
- ↑"Storing the information you need — Variables - Learn web development | MDN". developer.mozilla.org. 9 May 2023. Retrieved 23 June 2023.
- ↑"Values, Variables, and Literals - MDC". Mozilla Developer Network. 16 September 2010. Archived from the original on 29 June 2011. Retrieved 1 February 2020.
- ↑"JavaScript Hoisting". W3Schools. Archived from the original on 31 March 2022. Retrieved 17 December 2021.
In JavaScript, a variable can be declared after it has been used. In other words; a variable can be used before it has been declared.
- ↑"JavaScript Scoping and HoistingArchived 8 May 2021 at the Wayback Machine", Ben CherryArchived 28 February 2021 at the Wayback Machine, Adequately GoodArchived 8 March 2022 at the Wayback Machine, 8 February 2010
- ↑ECMA-262 5e edition clarified this behavior with the Declarative Environment Record and Object Environment Record. With this formalism, the global object is the Object Environment Record of the global Lexical Environment (the global scope).
- ↑"Number - JavaScript". MDN Web Docs. Retrieved 13 July 2025.
- 12"BigInt - Javascript". MDN Web Docs. Retrieved 13 July 2025.
- ↑"Template literals". MDN Web Docs. Archived from the original on 31 March 2022. Retrieved 4 November 2023.
- ↑"Comparison Operators - MDC Doc Center". Mozilla. 5 August 2010. Archived from the original on 4 May 2012. Retrieved 5 March 2011.
- ↑"The Elements of JavaScript Style". Douglas Crockford. Archived from the original on 17 March 2011. Retrieved 5 March 2011.
- ↑Orendorff, Jason. "ES6 In Depth: Symbols". Mozilla Hacks. Retrieved 13 July 2025.
- ↑"Spread syntax (...) - JavaScript | MDN". developer.mozilla.org. 25 September 2023.
- ↑"rest parameters". 9 September 2024. Archived from the original on 30 May 2018. Retrieved 29 September 2016.
- ↑"ECMAScript 2020 Language Specification". Ecma International. June 2020.
- ↑ECMA-262, Edition 3, 7.5.3 Future Reserved Words
- ↑Yadav, Amitya (4 October 2024). "Named function vs Anonymous Function Impacts". medium.com. Retrieved 19 February 2025.
- ↑"function*". mdm web docs. Retrieved 23 February 2025.
- ↑"ES6 Generators". medium.com. Retrieved 23 February 2025.
- ↑"await - JavaScript (MDN)". Retrieved 2 May 2017.
- ↑"jQuery Core 3.0 Upgrade Guide". Retrieved 2 May 2017.
- ↑"Taming the asynchronous beast with ES7". Retrieved 12 November 2015.
- ↑Foundation, Node.js (30 May 2017). "Node v8.0.0 (Current) - Node.js". Node.js.
- ↑"eval()". MDN Web Docs. Archived from the original on 1 April 2022. Retrieved 29 January 2020.
- 12"Documentation – TypeScript 5.2". www.typescriptlang.org. Archived from the original on 9 August 2024. Retrieved 9 November 2023.
- ↑"Handbook - Basic Types". www.typescriptlang.org. Retrieved 2 July 2025.
- ↑"TypeScript Language Specification p.24"(PDF). Archived from the original(PDF) on 17 November 2013.
- ↑"TypeScript: Documentation – Everyday Types". www.typescriptlang.org/. Archived from the original on 9 August 2024. Retrieved 30 March 2021.
- ↑Turner, Jonathan (18 June 2013). "Announcing TypeScript 0.9". TypeScript Language team blog. Microsoft. Archived from the original on 26 November 2013. Retrieved 18 June 2013.
- ↑"Generics in Typescript". Microsoft. Archived from the original on 5 April 2020. Retrieved 8 April 2020.
- ↑"Handbook - Unions and Intersection Types". www.typescriptlang.org. Retrieved 30 November 2020.
- ↑Sothmann, Sönke (31 January 2014). "An introduction to TypeScript's module system". blog.oio.de. Archived from the original on 1 February 2014. Retrieved 21 February 2014.
Further reading
- Danny Goodman: JavaScript Bible, Wiley, John & Sons, ISBN 0-7645-3342-8.
- David Flanagan, Paula Ferguson: JavaScript: The Definitive Guide, O'Reilly & Associates, ISBN 0-596-10199-6.
- Thomas A. Powell, Fritz Schneider: JavaScript: The Complete Reference, McGraw-Hill Companies, ISBN 0-07-219127-9.
- Axel Rauschmayer: Speaking JavaScript: An In-Depth Guide for Programmers, 460 pages, O'Reilly Media, 25 February 2014, ISBN 978-1449365035. (free online edition)
- Emily Vander Veer: JavaScript For Dummies, 4th Edition, Wiley, ISBN 0-7645-7659-3.
External links
- A re-introduction to JavaScript - Mozilla Developer Center
- JavaScript Loops
- ECMAScript standard references: ECMA-262
- Interactive JavaScript Lessons - example-based
- JavaScript Training
- Mozilla Developer Center Core References for JavaScript versions 1.5, 1.4, 1.3 and 1.2
- Mozilla JavaScript Language Documentation
- JavaScript
- بناء جملة لغة البرمجة
