كائن السلسلة في JavaScript

0 الأسهم
0
0
0
0

مقدمة

 

تُعدّ السلاسل النصية مفيدة لتخزين البيانات التي يمكن تمثيلها كنص. ومن أكثر العمليات شيوعًا على السلاسل النصية: التحقق من طولها، وبنائها ودمجها باستخدام عاملي الجمع (+) والمساواة (+=)، والتحقق من وجود أو موقع السلاسل الفرعية باستخدام دالة indexOf()، أو استخراج السلاسل الفرعية باستخدام دالة substring().

إنشاء سلاسل نصية

يمكن إنشاء السلاسل النصية بشكل بدائي، من السلسلة النصية الحرفية، أو ككائنات باستخدام الدالة البانية String():

const string1 = "A string primitive";
const string2 = 'Also a string primitive';
const string3 = `Yet another string primitive`;
const string4 = new String("A String object");

تتشابه أنواع البيانات النصية الأولية وكائنات البيانات النصية في العديد من السلوكيات، ولكنها تختلف أيضًا في جوانب أخرى مهمة وتتضمن بعض المحاذير. انظر "أنواع البيانات النصية الأولية وكائنات البيانات النصية" أدناه.

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

الوصول إلى الأحرف

هناك طريقتان للوصول إلى حرف في سلسلة نصية. الأولى هي طريقة charAt():

"cat".charAt(1); // gives value "a"

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

"cat"[1]; // gives value "a"

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

مقارنة السلاسل

استخدم عاملي المقارنة "أصغر من" و "أكبر من" لمقارنة السلاسل النصية:

const a = "a";
const b = "b";
if (a < b) {
// true
console.log(`${a} is less than ${b}`);
} else if (a > b) {
console.log(`${a} is greater than ${b}`);
} else {
console.log(`${a} and ${b} are equal.`);
}

لاحظ أن جميع عوامل المقارنة، بما في ذلك === و ==، تقارن السلاسل النصية مع مراعاة حالة الأحرف. ومن الطرق الشائعة لمقارنة السلاسل النصية مع مراعاة حالة الأحرف تحويل كلتيهما إلى نفس الحرف (كبير أو صغير) قبل مقارنتهما.

function areEqualCaseInsensitive(str1, str2) {
return str1.toUpperCase() === str2.toUpperCase();
}

يُعدّ اختيار التحويل باستخدام toUpperCase() أو toLowerCase() اختيارياً إلى حد كبير، ولا يتمتع أي منهما بالموثوقية الكاملة عند التوسع إلى ما هو أبعد من الأبجدية اللاتينية. على سبيل المثال، يتم تحويل الحرفين الألمانيين الصغيرين ß و ss إلى SS بواسطة toUpperCase()، بينما يتم الإبلاغ عن الحرف التركي ı بشكل خاطئ على أنه لا يساوي I بواسطة toLowerCase() إلا إذا تم استخدام toLocaleLowerCase ("tr") تحديداً.

const areEqualInUpperCase = (str1, str2) =>
str1.toUpperCase() === str2.toUpperCase();
const areEqualInLowerCase = (str1, str2) =>
str1.toLowerCase() === str2.toLowerCase();

areEqualInUpperCase("ß", "ss"); // true; should be false
areEqualInLowerCase("ı", "I"); // false; should be true

الحل المنطقي والقوي لاختبار المساواة غير الحساسة لحالة الأحرف هو استخدام واجهة برمجة التطبيقات Intl.Collator أو طريقة localeCompare() للسلسلة النصية - لديهم نفس الواجهة - مع تعيين خيار الحساسية إلى "accent" أو "base".

const areEqual = (str1, str2, locale = "en-US") =>
str1.localeCompare(str2, locale, { sensitivity: "accent" }) === 0;

areEqual("ß", "ss", "de"); // false
areEqual("ı", "I", "tr"); // true

تتيح طريقة localeCompare() مقارنة السلاسل بطريقة مشابهة لطريقة strcmp() - وهذا يسمح بفرز السلاسل بطريقة تراعي اللغة المحلية.

السلاسل الأولية وكائنات السلاسل

لاحظ أن لغة جافا سكريبت تميز بين كائنات السلاسل النصية وقيم السلاسل النصية الأولية. (وينطبق هذا أيضًا على القيم المنطقية والأرقام).

تُعتبر السلاسل النصية الحرفية (المحاطة بعلامات اقتباس مزدوجة أو مفردة) والسلاسل النصية المُعادة من استدعاءات السلاسل النصية في سياق غير بنائي (أي، عند استدعائها دون استخدام الكلمة المفتاحية `new`) سلاسل نصية أولية. في السياقات التي يُراد فيها استدعاء دالة على سلسلة نصية أولية أو عند إجراء بحث عن خاصية، يقوم جافا سكريبت تلقائيًا بتغليف السلسلة النصية الأولية واستدعاء الدالة أو إجراء البحث عن الخاصية على الكائن المُغلِّف.

const strPrim = "foo"; // A literal is a string primitive
const strPrim2 = String(1); // Coerced into the string primitive "1"
const strPrim3 = String(true); // Coerced into the string primitive "true"
const strObj = new String(strPrim); // String with new returns a string wrapper object.

console.log(typeof strPrim); // "string"
console.log(typeof strPrim2); // "string"
console.log(typeof strPrim3); // "string"
console.log(typeof strObj); // "object

تُعطي السلاسل النصية الأولية وكائنات السلاسل النصية نتائج مختلفة عند استخدام دالة eval(). تُعامل السلسلة النصية الأولية المُمرَّرة إلى eval كشفرة برمجية. أما كائنات السلاسل النصية، فتُعامل كغيرها من الكائنات، وذلك بإرجاعها كائنًا. على سبيل المثال:

const s1 = "2 + 2"; // creates a string primitive
const s2 = new String("2 + 2"); // creates a String object
console.log(eval(s1)); // returns the number 4
console.log(eval(s2)); // returns the string "2 + 2"

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

يمكن دائمًا تحويل كائن السلسلة النصية إلى نظيره الأصلي باستخدام طريقة valueOf().

console.log(eval(s2.valueOf())); // returns the number 4

إجبار السلسلة

تقوم العديد من العمليات المدمجة التي تتوقع سلاسل نصية بتحويل وسيطاتها أولاً إلى سلاسل نصية (وهذا هو سبب تصرف كائنات String كسلاسل نصية أولية). ويمكن تلخيص هذه العمليات على النحو التالي:

  • يتم إرجاع السلاسل النصية كما هي.
  • يصبح غير المعرّف "غير معرّف".
  • يصبح null "فارغًا".
  • يصبح الصواب "صواباً". ويصبح الخطأ "خطأً".
  • يتم تحويل الأرقام بنفس خوارزمية toString(10).
  • يتم تحويل BigInts بنفس خوارزمية toString(10).
  • تُثير الرموز خطأً من نوع TypeError.
  • يتم أولاً تحويل الكائنات إلى نوع بيانات أولي عن طريق استدعاء الدوال التالية: [Symbol.toPrimitive]() (مع استخدام "string" كتلميح)، و toString()، و valueOf()، على التوالي. ثم يتم تحويل نوع البيانات الأولي الناتج إلى سلسلة نصية.

توجد طرق مختلفة لتحقيق نفس التأثير تقريبًا في جافا سكريبت.

  • حرفيًا: يقوم التعبير `${x}` بتنفيذ خطوات ربط السلسلة الموضحة أعلاه للتعبير المضمن.
  • الدالة String(): تستخدم الدالة String(x) نفس الخوارزمية لتحويل x، باستثناء أن Symbols لا تثير خطأ TypeError، ولكنها تُرجع "Symbol(description)"، حيث يكون description هو وصف الرمز.
  • باستخدام عامل الجمع (+): "" + x يُحوّل المعامل إلى نوع بيانات أولي بدلاً من سلسلة نصية، وبالنسبة لبعض الكائنات، يكون سلوكه مختلفًا تمامًا عن تحويل السلاسل النصية العادية. راجع صفحة المرجع الخاصة به لمزيد من التفاصيل.

بحسب حالة الاستخدام الخاصة بك، قد ترغب في استخدام `${x}` (لمحاكاة السلوك المدمج) أو String(x) (للتعامل مع قيم الرموز دون التسبب في أخطاء)، ولكن لا يجب عليك استخدام "" + x. .

أحرف UTF-16، ونقاط ترميز Unicode، ومجموعات الرسوم البيانية

تُمثَّل السلاسل النصية أساسًا كسلسلة من وحدات ترميز UTF-16. في ترميز UTF-16، يبلغ طول كل وحدة ترميز 16 بتًا بالضبط. هذا يعني أن هناك حدًا أقصى يبلغ 216 أو 65,536 حرفًا ممكنًا كوحدة ترميز UTF-16 واحدة. تُسمى مجموعة الأحرف هذه صفحة اللغات المتعددة الأساسية (BMP) وتتضمن الأحرف الأكثر شيوعًا مثل اللاتينية واليونانية والسيريلية والعديد من أحرف شرق آسيا. يمكن كتابة كل وحدة ترميز في سلسلة نصية باستخدام \u متبوعة بأربعة أرقام سداسية عشرية بالضبط.

مع ذلك، فإن مجموعة أحرف يونيكود الكاملة أكبر بكثير من 65536 حرفًا. تُخزَّن الأحرف الإضافية في UTF-16 على شكل أزواج بديلة، وهي أزواج من وحدات ترميز 16 بت تُمثِّل حرفًا واحدًا. ولتجنب الالتباس، يجب أن تكون قيم جزئي الزوج بين 0xD800 و0xDFFF، ولا تُستخدم وحدات الترميز هذه لترميز الأحرف ذات الترميز الواحد. (وبشكل أدق، تتراوح قيم البدائل البادئة، والتي تُسمى أيضًا وحدات الترميز البديلة العليا، بين 0xD800 و0xDBFF، بينما تتراوح قيم البدائل اللاحقة، والتي تُسمى أيضًا وحدات الترميز البديلة السفلى، بين 0xDC00 و0xDFFF، بما في ذلك حرف يونيكود). يُطلق على الحرف المُكوَّن من وحدة ترميز واحدة أو وحدتين من UTF-16 اسم نقطة ترميز يونيكود. يمكن كتابة أي نقطة رمز Unicode في سلسلة باستخدام \u{xxxxxx}، حيث يمثل xxxxxx من 1 إلى 6 أرقام سداسية عشرية.

"البديل الفردي" هو وحدة رمزية مكونة من 16 بت تتوافق مع أحد الأوصاف التالية:

  • في النطاق 0xD800–0xDBFF، شاملًا (أي، هو بديل رائد)، ولكنه آخر وحدة رمزية في السلسلة، أو أن وحدة الرمز التالية ليست بديلًا أخيرًا.
  • في النطاق 0xDC00–0xDFFF، شاملًا (أي، البديل الأخير)، ولكن وحدة التعليمات البرمجية الأولى في السلسلة، أو وحدة التعليمات البرمجية السابقة ليست البديل الأصلي.

لا تمثل الأحرف البديلة المفردة أي أحرف يونيكود. على الرغم من أن معظم دوال جافا سكريبت الداخلية تتعامل معها بشكل صحيح، نظرًا لأنها جميعًا تعمل على وحدات ترميز UTF-16، إلا أن الأحرف البديلة المفردة لا تُعد عادةً قيمًا صالحة عند التفاعل مع أنظمة أخرى - على سبيل المثال، تُصدر الدالة encodeURI() خطأ URIE للأحرف البديلة المفردة، لأن ترميز URI يستخدم ترميز UTF-8، الذي لا يدعم الأحرف البديلة المفردة. تُسمى السلاسل النصية التي لا تحتوي على أي أحرف بديلة مفردة بالسلاسل النصية السليمة، وهي آمنة للاستخدام مع الدوال التي لا تتعامل مع UTF-16 (مثل encodeURI() أو TextEncoder). يمكنك التحقق من سلامة بنية السلسلة النصية باستخدام الدالة isWellFormed()، أو إزالة الأحرف البديلة المفردة باستخدام الدالة toWellFormed().

فوق أحرف يونيكود، يوجد تسلسل محدد من أحرف يونيكود يجب اعتباره كوحدة بصرية، يُعرف باسم المجموعة الرسومية. وأكثر الأمثلة شيوعًا هي الرموز التعبيرية: فالعديد من الرموز التعبيرية، التي لها نطاق واسع من التنوع، تتكون في الواقع من عدة رموز تعبيرية، عادةً ما تحتوي على الحرف (U+200D) ينضمان معًا.

يجب توخي الحذر عند تحديد مستوى الأحرف التي يتم التكرار عليها. على سبيل المثال، تقوم الدالة split(“”) بتقسيم الأحرف حسب وحدات ترميز UTF-16 وفصل الأزواج البديلة. تشير مؤشرات السلاسل النصية أيضًا إلى فهرس كل وحدة ترميز UTF-16. من ناحية أخرى، تقوم الدالة [Symbol.iterator]() بالتكرار حسب نقاط ترميز Unicode. يتطلب التكرار عبر مجموعات الرسوم البيانية كتابة كود مخصص.

"😄".split(""); // ['\ud83d', '\ude04']; splits into two lone surrogates
// "Backhand Index Pointing Right: Dark Skin Tone"
[..."👉🏿"]; // ['👉', '🏿']
// splits into the basic "Backhand Index Pointing Right" emoji and
// the "Dark skin tone" emoji
// "Family: Man, Boy"
[..."👨‍👦"]; // [ '👨', '‍', '👦' ]
// splits into the "Man" and "Boy" emoji, joined by a ZWJ
// The United Nations flag
[..."🇺🇳"]; // [ '🇺', '🇳' ]
// splits into two "region indicator" letters "U" and "N".
// All flag emojis are formed by joining two region indicator letters

منشئ

خيط()

يقوم بإنشاء كائنات نصية. عند استدعائه كدالة، فإنه يُرجع قيمًا أولية من نوع نصي.

الأساليب الثابتة

String.fromCharCode()

تُعيد هذه الدالة سلسلة نصية تم إنشاؤها باستخدام التسلسل المحدد لقيم Unicode.

String.fromCodePoint()

تُعيد هذه الدالة سلسلة نصية تم إنشاؤها باستخدام التسلسل المحدد لنقاط الترميز.

String.raw()

يُعيد سلسلة نصية تم إنشاؤها من سلسلة نمطية خام.

خصائص العينة

يتم تعريف هذه الخصائص في String.prototype ويتم مشاركتها بواسطة جميع مثيلات String.

String.prototype.constructor

دالة البناء التي تُنشئ كائن النسخة. بالنسبة لنسخ السلاسل النصية، تكون القيمة الأولية هي دالة البناء الخاصة بالسلاسل النصية.

هذه الخصائص خاصة بكل سلسلة نصية.

طول

يعكس طول السلسلة. للقراءة فقط.

أساليب العينات

String.prototype.at()

تُعيد هذه الدالة الحرف (وحدة ترميز UTF-16 واحدة بالضبط) الموجود في الفهرس المُحدد. تقبل هذه الدالة أعدادًا صحيحة سالبة تبدأ العد التنازلي من آخر حرف في السلسلة النصية.

String.prototype.charAt()

يُرجع الحرف (وحدة ترميز UTF-16 واحدة بالضبط) في الفهرس المحدد.

سلسلة.النموذج الأولي.charCodeAt()

تُرجع هذه الدالة رقمًا يمثل قيمة وحدة ترميز UTF-16 عند الفهرس المحدد.

String.prototype.codePointAt()

تُرجع هذه الدالة عددًا صحيحًا غير سالب يمثل قيمة نقطة الترميز لنقطة الترميز المشفرة بنظام UTF-16 بدءًا من الوضع المحدد.

String.prototype.concat()

يجمع النص سلسلتين نصيتين (أو أكثر) ويعيد سلسلة نصية جديدة.

String.prototype.endsWith()

يحدد ما إذا كانت السلسلة تنتهي بأحرف السلسلة searchString.

String.prototype.includes()

يحدد ما إذا كانت سلسلة الاستدعاء تحتوي على سلسلة بحث.

String.prototype.indexOf()

يُرجع هذا الأمر فهرس أول ظهور لـ searchValue في هذه السلسلة، أو -1 إذا لم يتم العثور عليه.

String.prototype.isWellFormed()

يُرجع قيمة منطقية تشير إلى ما إذا كانت هذه السلسلة تحتوي على استبدالات فردية.

String.prototype.lastIndexOf()

يُرجع هذا الأمر فهرس آخر ظهور لـ searchValue في هذه السلسلة، أو -1 إذا لم يتم العثور عليه.

String.prototype.localeCompare()

تُرجع هذه الدالة رقمًا يشير إلى ما إذا كانت السلسلة المشار إليها بواسطة compareString تسبق السلسلة المعطاة أو تليها أو تعادلها في ترتيب الفرز.

String.prototype.match()

يُستخدم لمطابقة تعبير نمطي (regexp) مع سلسلة نصية.

String.prototype.matchAll()

يُعيد هذا الأمر مُكرِّرًا لجميع مُطابقات التعبير النمطي.

String.prototype.normalize()

تُعيد الصيغة الموحدة لـ Unicode قيمة السلسلة المُستدعاة.

String.prototype.padEnd()

يقوم هذا الأمر بدمج السلسلة الحالية من النهاية مع سلسلة أخرى، ويعيد سلسلة جديدة بطول targetLength.

String.prototype.padStart()

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

String.prototype.repeat()

تُرجع سلسلة نصية تتكون من عناصر الكائن محسوبة عدد مرات ظهورها.

String.prototype.replace()

تُستخدم دالة SearchFor لاستبدال العناصر باستخدام دالة replaceWith. قد تكون دالة searchFor سلسلة نصية أو تعبيرًا نمطيًا، وقد تكون دالة replaceWith سلسلة نصية أو دالة.

String.prototype.replaceAll()

تُستخدم الدالة SearchFor لاستبدال جميع حالات استخدام الدالة replaceWith. قد تكون الدالة searchFor سلسلة نصية أو تعبيرًا نمطيًا، وقد تكون الدالة replaceWith سلسلة نصية أو دالة.

ابحث عن تطابق بين تعبير نمطي regexp والسلسلة النصية المُستدعاة.

String.prototype.slice()

يستخرج جزءًا من سلسلة نصية ويعيد سلسلة نصية جديدة.

String.prototype.split()

تُرجع هذه الدالة مصفوفة من السلاسل النصية التي يتم ملؤها عن طريق تقسيم السلسلة النصية الأصلية إلى سلاسل فرعية من السلسلة النصية sep.

String.prototype.startsWith()

يحدد ما إذا كانت سلسلة الاستدعاء تبدأ بالأحرف الموجودة في سلسلة البحث.

تم إيقاف استخدام الدالة String.prototype.substr()

تُعيد جزءًا من سلسلة نصية تبدأ من الفهرس المحدد وتمتد لعدد محدد من الأحرف.

String.prototype.substring()

يُعيد سلسلة نصية جديدة تحتوي على أحرف السلسلة النصية المُستدعاة من (أو بين) الفهرس (أو الفهارس) المُحدد.

سلسلة.النموذج الأولي.إلى الحالة المحلية السفلى

يتم تحويل الأحرف داخل السلسلة إلى أحرف صغيرة مع مراعاة اللغة المحلية الحالية.

بالنسبة لمعظم اللغات، فإن هذا يُعيد نفس الحالة التي تُعيدها الدالة toLowerCase().

String.prototype.toLocaleUpperCase()

يتم تحويل الأحرف داخل السلسلة إلى أحرف كبيرة مع مراعاة اللغة المحلية الحالية.

بالنسبة لمعظم اللغات، فإن هذا يعيد نفس الحالة التي تعيدها الدالة toUpperCase().

String.prototype.toLowerCase()

يُعيد قيمة السلسلة النصية المُستدعاة بعد تحويلها إلى أحرف صغيرة.

String.prototype.toString()

تُعيد هذه الدالة سلسلة نصية تُمثل الكائن المُحدد. وهي تُعيد تعريف دالة Object.prototype.toString().

String.prototype.toUpperCase()

يُعيد قيمة السلسلة النصية المُستدعاة بعد تحويلها إلى أحرف كبيرة.

String.prototype.toWellFormed()

تُرجع هذه الدالة سلسلة نصية يتم فيها استبدال جميع حالات ظهور هذه السلسلة النصية بحرف الاستبدال Unicode U+FFFD.

String.prototype.trim()

يقوم بإزالة المسافات البيضاء من بداية ونهاية السلسلة.

String.prototype.trimEnd()

يقوم بقص نهاية السلسلة مع ترك مسافة بيضاء.

String.prototype.trimStart()

يقوم بإزالة المسافات البيضاء من بداية السلسلة.

String.prototype.valueOf()

تُعيد هذه الدالة القيمة الأولية للكائن المُحدد. وهي تُعيد تعريف دالة Object.prototype.valueOf().

String.prototype[Symbol.iterator]()

يُعيد كائن مُكرِّر جديد يتكرر على نقاط الترميز لقيمة سلسلة نصية، ويعيد كل نقطة ترميز كقيمة سلسلة نصية.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

قد يعجبك أيضاً