Menu
العربية
جرّب في Playground

السلاسل النصية والقوالب الحرفية في JavaScript

شرح عملي للنصوص في JavaScript: علامات التنصيص، الـ Backticks، حقن المتغيرات، النصوص متعددة الأسطر، وأهم الدوال التي ستستخدمها فعلياً.

ثلاث طرق لكتابة السلاسل النصية في JavaScript

توفّر لك JavaScript ثلاثة محدِّدات للسلاسل النصية. اثنان منها متبادلان تمامًا، أما الثالث فيقدّم لك ما هو أكثر من مجرد احتواء النص.

index.js
Output
Click Run to see the output here.

علامات التنصيص المفردة والمزدوجة تُنتج نفس السلسلة النصية تمامًا — اختر واحدة والتزم بها (معظم المشاريع الحديثة تعتمد على المفردة افتراضيًا، أو تترك الأمر لأداة التنسيق). أما backticks فتُنتج ما يُعرف بـ template literal، وهنا يبدأ الجزء الممتع: فهي تسمح بحقن المتغيرات داخل النص وبكتابة نص متعدد الأسطر.

خلف الكواليس، الأنواع الثلاثة تُنتج نفس نوع السلسلة النصية الأولي. فاختيار المحدِّد مجرد مسألة شكلية لا أكثر.

تسلسلات الهروب وتضمين علامات التنصيص

داخل أي سلسلة نصية، الشرطة المائلة العكسية \ تبدأ تسلسل هروب. أشهرها: \n (سطر جديد)، و\t (مسافة جدولة)، و\\ (شرطة مائلة عكسية فعلية)، إضافة إلى \" و\' لتضمين نفس نوع علامة التنصيص التي افتتحت بها السلسلة:

index.js
Output
Click Run to see the output here.

يمكنك الاستغناء عن معظم محارف الـ escape بمجرد اختيار نوع الاقتباس الآخر: العبارة 'She said "hi" and left.' لا تحتاج أي backslashes. المرونة أفضل من التعصب للقواعد.

template literals في جافا سكريبت: قوة الـ backtick الخفية

الـ template literal يقدّم لك ميزتين لا تجدهما في السلاسل النصية العادية. أولاً، يتيح لك حقن المتغيرات داخل النص عبر ${...}:

index.js
Output
Click Run to see the output here.

كل ما يوجد داخل ${...} هو تعبير (expression) في JavaScript، وليس مجرد اسم متغير. فيمكنك كتابة عمليات حسابية، أو استدعاء دوال، أو استخدام الشرط الثلاثي (ternary)، بل حتى template literals أخرى متداخلة — كل ذلك مسموح:

index.js
Output
Click Run to see the output here.

ثانيًا، تدعم الـ template literals في جافا سكريبت كتابة نص متعدد الأسطر دون الحاجة إلى \n:

index.js
Output
Click Run to see the output here.

الأسطر الجديدة داخل النص المصدر تُحفظ كما هي في السلسلة الناتجة. ولهذا السبب، إذا كنت تتعامل مع أي نص أطول من مجرد كلمة أو عنوان صغير، فالـ backtick هو الخيار الصحيح في معظم الأحيان.

حقن المتغيرات في النصوص أفضل من الدمج اليدوي

قبل ظهور template literals في جافا سكريبت، كانت الطريقة الوحيدة لبناء سلسلة نصية ديناميكية هي استخدام معامل الجمع +:

index.js
Output
Click Run to see the output here.

كلا الأسلوبين يعطي نفس الناتج. فرق template literals في جافا سكريبت إنها تُقرأ زي الجملة اللي تبنيها فعلاً، بينما طريقة + تجبرك تتابع علامات التنصيص والمسافات وعلامات الدمج وحدة وحدة. استخدم + فقط لما تضيف شيء صغير لنص موجود. أما لو النص أطول من كذا، روح مباشرة للـ backtick.

السلاسل النصية غير قابلة للتعديل

كل دالة تبدو وكأنها تعدّل على السلسلة النصية، هي في الحقيقة ترجّع سلسلة جديدة:

index.js
Output
Click Run to see the output here.

إذا أردت أن يحدث التغيير فعلاً، لازم تُسنِد الناتج إلى متغير. هذه النقطة تُوقِع المبتدئين في فخ شائع: يكتبون s.replace("a", "b") ويتوقعون أن قيمة s ستتغير، لكن هذا لا يحدث. السلاسل النصية في javascript تتصرف مثل الأرقام تماماً: القيمة نفسها لا يمكن تعديلها، كل ما يمكنك فعله هو توجيه المتغير إلى قيمة جديدة.

دوال النصوص في javascript التي ستستخدمها فعلاً

واجهة السلاسل النصية في javascript ضخمة ومليئة بالدوال، لكن في الواقع اليومي ستجد نفسك تعتمد على حفنة صغيرة منها فقط:

index.js
Output
Click Run to see the output here.

بعض النقاط التي يستحسن حفظها:

  • length خاصية وليست دالة — بدون أقواس.
  • replace مع نص عادي يستبدل أول تطابق فقط. لاستبدال جميع المطابقات استخدم replaceAll أو تعبيرًا نمطيًا مع الراية g.
  • slice(start, end) يأخذ مجالًا نصف مفتوح: الحرف عند end غير مُضَمَّن.
  • الفهارس السالبة في slice تُحسب من النهاية: s.slice(-3) يُرجع آخر ثلاثة أحرف.

الفهرسة والمرور على أحرف النص

تتصرف السلاسل النصية في javascript وكأنها مصفوفات أحرف للقراءة فقط. يمكنك الوصول إلى أي حرف عبر فهرسه والمرور على الأحرف واحدًا تلو الآخر، لكن لا يمكنك تعديل حرف في موضع معيّن:

index.js
Output
Click Run to see the output here.

for...of يمرّ على نقاط الترميز (code points)، وهذا يتعامل مع معظم محارف يونيكود بشكل صحيح. أما الوصول عبر الفهرس (s[i]) فيمرّ على وحدات ترميز UTF-16، وقد يقطع الإيموجي والمحارف خارج نطاق BMP نصفين. في النصوص العادية كلا الأسلوبين يفي بالغرض، لكن مع أي محتوى يُدخله المستخدم، يُفضَّل استخدام for...of أو [...s].

Tagged Template Literals في javascript

يبقى شكل أخير يستحق المعرفة، حتى لو لم تكتبه كثيرًا. الـ tagged template literal عبارة عن استدعاء لدالة تمرَّر إليها أجزاء النص الثابتة والقيم المحقونة كمعاملات منفصلة:

index.js
Output
Click Run to see the output here.

الدالة الوسم (tag function) هي اللي تقرر شكل النص النهائي — ممكن تستخدمها لتهريب HTML، أو بناء استعلامات SQL بشكل آمن، أو توليد CSS، أو تحليل GraphQL. راح تشوف هذا النمط في مكتبات مثل styled-components وgraphql-tag وlit-html أكثر بكثير من احتياجك لكتابته بنفسك. لكن لما تحتاج معالجة نصية مخصصة، الـ tagged templates هي أنظف أداة للمهمة.

أخطاء شائعة ينبغي الانتباه لها

قائمة مختصرة بالأشياء اللي يتعثر فيها الكثيرون:

  • نسيان إسناد نتيجة التابع. s.trim() لا يفعل شيئًا لوحده، لازم تسند الناتج لمتغير.
  • استخدام + لدمج رقم مع نص. نتيجة "Age: " + 30 + 5 هي "Age: 305" وليست "Age: 35". الـ template literals تتجنب هذه المشكلة: `Age: ${30 + 5}`.
  • الخلط بين == ومقارنة النصوص. راح نغطي موضوع المساواة بتفصيل لاحقًا، لكن "1" == 1 تعطي true بينما "1" === 1 تعطي false. فضّل استخدام === دائمًا.
  • افتراض أن length يساوي عدد الأحرف. مع الإيموجي وغيرها من المحارف التي تستخدم surrogate pairs، قيمة "🙂".length هي 2 وليست 1. استخدم [..."🙂"].length أو Array.from(s).length لما تحتاج عدد المحارف كما يراها المستخدم.

التالي: الأرقام و BigInt

النصوص نوع واحد من الأنواع البدائية، والأرقام نوع آخر. نظام الأرقام في جافا سكريبت له خصوصياته الغريبة — نوع Number واحد يشمل الأعداد الصحيحة والعشرية معًا، إضافةً إلى BigInt للحالات التي لا يكفي فيها ذلك. وهذا موضوع الصفحة التالية.

الأسئلة الشائعة

ما الفرق بين علامات التنصيص والـ backticks في JavaScript؟

علامتا التنصيص المفردة (') والمزدوجة (") تُنشئان سلسلة نصية عادية، وهما متبادلتان تماماً. أما الـ backticks (`) فتُنشئ ما يُعرف بالـ template literals، وتدعم حقن القيم عبر ${...} وكتابة النص على عدة أسطر دون الحاجة لرموز الهروب. القاعدة البسيطة: استخدم الـ backticks كلما احتجت إلى إدراج متغيّر أو كتابة نص يمتد على أكثر من سطر.

كيف أُدرج متغيّراً داخل نص في JavaScript؟

الطريقة الأنظف هي استخدام template literal: ضع النص بين علامتي backtick واكتب التعبير داخل ${...}. مثلاً `Hello, ${name}!` يُقيّم name ويضع قيمته مكانه. ويمكنك وضع أي تعبير بالداخل: ${a + b} أو ${user.name.toUpperCase()}، بل حتى template literal آخر متداخل.

هل السلاسل النصية في JavaScript غير قابلة للتعديل (immutable)؟

نعم، وهذه نقطة مهمة. كل دوال النصوص مثل toUpperCase وslice وreplace تُرجع سلسلة جديدة ولا تُعدّل الأصلية. فلو كتبت s.toUpperCase() دون إسناد الناتج إلى متغيّر، فلن يتغيّر شيء. المبدأ نفسه موجود في Python وJava.

ما هي الـ tagged template literals؟

الـ tagged template literal يسمح لك بتمرير محتوى القالب إلى دالة تستقبل الأجزاء النصية والقيم المحقونة كمعاملات منفصلة. فمثلاً tag`Hello, ${name}` يُترجم إلى استدعاء tag(["Hello, ", ""], name). مكتبات مثل styled-components وgraphql-tag تعتمد على هذه الفكرة لتحليل القالب أو تحويله قبل إنتاج القيمة النهائية.

تعلّم البرمجة مع Coddy

ابدأ الآن