مسار لفهم القوالب الحرفية في JavaScript

أضافت مواصفات ECMAScript ، التي تم إصدارها في 2015 ( ES6 ) ، ميزة جديدة إلى JavaScript - القوالب الحرفية. تعطينا القوالب الحرفية آلية جديدة لإنشاء قيم السلسلة... تحتوي هذه الآلية على العديد من الميزات القوية ، مثل تبسيط إنشاء بنيات متعددة الخطوط واستخدام العناصر النائبة لتضمين نتائج التعبير في السلاسل. بالإضافة إلى ذلك ، هناك احتمال آخر هنا - حرفيّات القوالب الموسومة. هذا شكل ممتد من القوالب الحرفية. تتيح لك قوالب العلامات إنشاء سلاسل باستخدام التعبيرات داخل السلاسل واستخدام وظائف خاصة. كل هذا يوسع قدرة المبرمجين على العمل مع السلاسل ، مما يسمح ، على سبيل المثال ، بإنشاء سلاسل ديناميكية يمكن أن تكون عناوين URL ، أو كتابة وظائف لضبط عناصر HTML .







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



التصريح عن السلاسل



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



يمكن اعتبار سلسلة JavaScript كسلسلة من الأحرف محاطة بعلامات اقتباس مفردة ( ' '):



const single = 'Every day is a good day when you paint.'


هناك طريقة أخرى لتصريح الجمل وهي استخدام علامات الاقتباس المزدوجة ( " "):



const double = "Be so very light. Be a gentle whisper."


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



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



//     ,   
const single = '"We don\'t make mistakes. We just have happy accidents." - Bob Ross'

//     ,   
const double = "\"We don't make mistakes. We just have happy accidents.\" - Bob Ross"

console.log(single);
console.log(double);


log()سيؤدي استدعاء زوج من الأساليب إلى إرسال سطرين متطابقين إلى وحدة التحكم .



"We don't make mistakes. We just have happy accidents." - Bob Ross
"We don't make mistakes. We just have happy accidents." - Bob Ross


من ناحية أخرى ، يتم التصريح عن القوالب الحرفية باستخدام backticks ( ` `):



const template = `Find freedom on this canvas.`


ليست هناك حاجة للهروب من الاقتباسات المفردة أو المزدوجة هنا:



const template = `"We don't make mistakes. We just have happy accidents." - Bob Ross


لكن يجب إفلات backticks في مثل هذه السلاسل:



const template = `Template literals use the \` character.`


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



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



سلاسل متعددة الخطوط



في هذا القسم ، سنتحدث أولاً عن كيفية الإعلان عن السلاسل متعددة الأسطر قبل ES6 ، ثم سننظر في كيفية تبسيط القوالب الحرفية لهذه المهمة.



في البداية ، إذا كان عليك إدخال متغير سلسلة يتكون من عدة أسطر في محرر نصي ، فسيتم استخدام عامل تشغيل سلسلة السلسلة . يوضح مثال تسلسل السلسلة التالي هذه الفكرة:



const address =
  'Homer J. Simpson' +
  '742 Evergreen Terrace' +
  'Springfield'


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



Homer J. Simpson742 Evergreen TerraceSpringfield


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



const address =
  'Homer J. Simpson\
  742 Evergreen Terrace\
  Springfield'


يحتفظ هذا الأسلوب ، على سبيل المثال ، بالمسافات الموجودة قبل أجزاء السطر ، ولكن قيمة المتغير ، إذا قمت بطباعتها على وحدة التحكم ، سيتم تمثيلها مرة أخرى بسطر واحد:



Homer J. Simpson  742 Evergreen Terrace  Springfield


يمكنك إنشاء سلسلة حقيقية متعددة الأسطر باستخدام حرف تغذية الأسطر ( \n):



const address =
  'Homer J. Simpson\n' +
  '742 Evergreen Terrace\n' +
  'Springfield'


عند عرض قيمة سلسلة مخزنة في وحدة التحكم address، ستمتد هذه القيمة على عدة أسطر:



Homer J. Simpson
742 Evergreen Terrace
Springfield


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



const address = `Homer J. Simpson
742 Evergreen Terrace
Springfield`


إذا قمت بإخراج هذا الثابت إلى وحدة التحكم ، فسيبدو النص كما هو في المحرر:



Homer J. Simpson
742 Evergreen Terrace
Springfield


هنا يجب أن يؤخذ في الاعتبار أنه في حالة وجود مسافات بين backticks المستخدمة لمحاذاة الكود ، فسيتم تضمين هذه المسافات في القالب الحرفي النهائي. تأمل المثال التالي:



const address = `Homer J. Simpson
                 742 Evergreen Terrace
                 Springfield`


على الرغم من أن هذا النمط من الترميز يسهل القراءة ، إلا أن ما يصل إلى وحدة التحكم بعد إخراجها لن يبدو جذابًا للغاية:



Homer J. Simpson
                 742 Evergreen Terrace
                 Springfield


الآن ، بعد أن تعاملنا مع سلاسل متعددة الأسطر ، دعنا نتحدث عن كيفية تضمين نتائج تقييم التعبيرات المختلفة في سلاسل معرّفة بطرق مختلفة ، أي دعونا نتحدث عن استيفاء التعبيرات.



إقحام التعبيرات



في السابق ، قبل ES6 ، تم استخدام التسلسل لإنشاء سلاسل ديناميكية تم تشكيلها بواسطة قيم متغيرة أو تعبير:



const method = 'concatenation'
const dynamicString = 'This string is using ' + method + '.'


إذا خرجت dynamicStringإلى وحدة التحكم ، فستحصل على ما يلي:



This string is using concatenation.


عند استخدام القوالب الحرفية ، يمكن تضمين التعبيرات في السلسلة باستخدام العناصر النائبة. العنصر النائب هو بناء عرض ${}. في هذه الحالة ، يعتبر كل شيء موجود في الأقواس المتعرجة كود JavaScript ، وكل شيء خارج هذا البناء يعتبر سلسلة:



const method = 'interpolation'
const dynamicString = `This string is using ${method}.`


عند الإخراج dynamicStringإلى وحدة التحكم ، تحصل على النتيجة التالية:



This string is using interpolation.


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



function createOAuthString(host, clientId, scope) {
  return host + '/login/oauth/authorize?client_id=' + clientId + '&scope=' + scope
}

createOAuthString('https://github.com', 'abc123', 'repo,user')


إذا قمت بطباعة نتيجة هذه الوظيفة على وحدة التحكم ، فستحصل على ما يلي:



https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user


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



function createOAuthString(host, clientId, scope) {
  return `${host}/login/oauth/authorize?client_id=${clientId}&scope=${scope}`
}

createOAuthString('https://github.com', 'abc123', 'repo,user')


ستكون نتيجة الوظيفة كما يلي:



https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user


يمكنك استخدام طريقة trim () لإزالة المسافة البيضاء البادئة والزائدة من سلسلة تم إنشاؤها باستخدام قالب حرفي . على سبيل المثال ، في مقتطف التعليمات البرمجية التالي لإنشاء عنصر HTMLمع مرجع مخصص ، يتم استخدام وظيفة السهم :



const menuItem = (url, link) =>
  `
<li>
  <a href="${url}">${link}</a>
</li>
`.trim()

menuItem('https://google.com', 'Google')


ستتم إزالة المسافات البادئة والزائدة من السطر الأخير لضمان تقديم العنصر بشكل صحيح:



<li>
  <a href="https://google.com">Google</a>
</li>


يمكن استيفاء التعبيرات الكاملة وليس المتغيرات فقط. على سبيل المثال - مثل هنا ، حيث يتم تضمين نتيجة إضافة رقمين في سلسلة:



const sum = (x, y) => x + y
const x = 5
const y = 100
const string = `The sum of ${x} and ${y} is ${sum(x, y)}.`

console.log(string)


هنا يتم التصريح عن الوظيفة sum()والثوابت xو y. بعد ذلك ، يستخدم الخط كلاً من الوظيفة وهذه الثوابت. هذا ما يبدو عليه الثابت stringعند طباعته على وحدة التحكم:



The sum of 5 and 100 is 105.


يمكن أن تكون هذه الآلية مفيدة بشكل خاص عند استخدام عامل التشغيل الثلاثي ، والذي يسمح لك بفحص الشروط عند تكوين سلسلة:



const age = 19
const message = `You can ${age < 21 ? 'not' : ''} view this page`
console.log(message)


messageيمكن أن يتغير الثابت المطبوع على وحدة التحكم ، بناءً على ما إذا كان أكبر من أو أقل من 21 ، القيمة المخزنة فيه age. نظرًا لأن هذه القيمة هي 19 في مثالنا ، فسيتم إرسال ما يلي إلى وحدة التحكم:



You can not view this page


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



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



تعد قوالب العلامات نموذجًا موسعًا للقوالب الحرفية. تبدأ القوالب ذات العلامات بوظيفة ذات علامات تحلل القالب الحرفي ، مما يمنح المطور مزيدًا من التحكم في عملية إنشاء السلسلة الديناميكية.



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



function tag(strings, ...expressions) {
  console.log(strings)
  console.log(expressions)
}


إذا كنت تستخدم وظيفة عند إنشاء قالب علامة tag، فيمكنك الحصول على البنية التالية:



const string = tag`This is a string with ${true} and ${false} and ${100} interpolated inside.`


لأن وظيفة tagالانتاج ينفذ إلى وحدة التحكم stringsو expressions، عند تنفيذ هذا الرمز، سيتم إرسال ما يلي إلى وحدة التحكم:



["This is a string with ", " and ", " and ", " interpolated inside."]
[true, false, 100]


يمكنك أن ترى أن المعامل الأول strings، هو مصفوفة تحتوي على جميع السلاسل الحرفية:



"This is a string with "
" and "
" and "
" interpolated inside."


تحتوي هذه الوسيطة أيضًا على خاصية rawيمكنك الرجوع إليها باسم strings.raw. يحتوي على سطر لم تتم معالجة أي تسلسلات هروب عليه. على سبيل المثال ، \nسيكون مجرد حرف \n، وليس أمر تغذية سطر.



المعامل الثاني ...expressionsهو مصفوفة تحتوي على جميع التعبيرات:



true
false
100


والنتيجة هي أن tagالقيم الحرفية والتعبيرات السلسلة يتم تمريرها إلى وظيفة قالب العلامة . لاحظ أن الوظيفة غير مطلوبة لإرجاع سلسلة. يمكنه العمل مع القيم التي تم تمريرها إليه وإرجاع أي شيء. على سبيل المثال ، قد يكون لدينا وظيفة لا تولي أي اهتمام لأي شيء وتعود فقط null. هذه هي الطريقة التي تتم بها كتابة الوظيفة returnsNullفي المثال التالي:



function returnsNull(strings, ...expressions) {
  return null
}

const string = returnsNull`Does this work?`
console.log(string)


نتيجة لتنفيذ هذا الرمز ، سيظهر ما يلي في وحدة التحكم:



null


كمثال لما يمكنك القيام به في قالب مميز ، يمكنك إجراء تغييرات على كل تعبير ، مثل التغييرات لتضمين التعبيرات في علامات HTML. دعونا خلق وظيفة boldتضيف علامات إلى <strong>كل من </strong>بداية ونهاية كل التعبير:



function bold(strings, ...expressions) {
  let finalString = ''

  //    
  expressions.forEach((value, i) => {
    finalString += `${strings[i]}<strong>${value}</strong>`
  })

  //    
  finalString += strings[strings.length - 1]

  return finalString
}

const string = bold`This is a string with ${true} and ${false} and ${100} interpolated inside.`

console.log(string)


هنا ، expressionsيتم استخدام حلقة forEach لاجتياز المصفوفة . كل عنصر محاط بعلامات <strong></strong>.



This is a string with <strong>true</strong> and <strong>false</strong> and <strong>100</strong> interpolated inside.


في مكتبات JavaScript الشائعة ، يمكنك العثور على عدة أمثلة لاستخدام قوالب العلامات. على سبيل المثال ، تستخدم مكتبة علامات الرسم البياني قالبًا حرفيًا gqlلتحليل سلاسل استعلام GraphQL وتحويلها إلى شجرة بناء جملة مجردة (AST) تفهمها GraphQL:



import gql from 'graphql-tag'

//        5
const query = gql`
  {
    user(id: 5) {
      firstName
      lastName
    }
  }
`


تستخدم مكتبة مكوّنات النمط أيضًا وظيفة وضع العلامات لإنشاء مكونات React جديدة من عناصر DOM العادية وتطبيق أنماط CSS إضافية عليها :



import styled from 'styled-components'

const Button = styled.button`
  color: magenta;
`

// <Button>     


بدلاً من ذلك ، يمكنك استخدام طريقة String.raw القياسية لتطبيقها على القوالب ذات العلامات لمنع معالجة تسلسلات الهروب:



const rawString = String.raw`I want to write /n without it being escaped.`
console.log(rawString)


سيظهر ما يلي في وحدة التحكم بعد تنفيذ هذا الرمز:



I want to write /n without it being escaped.


النتيجة



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



هل تستخدم القالب الحرفي؟






All Articles