Введение
Строки полезны для хранения данных, которые можно представить в виде текста. К наиболее распространённым операциям над строками относятся проверка их длины, построение и конкатенация с помощью строковых операторов + и +=, проверка наличия или расположения подстрок с помощью метода 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(), в то время как турецкая буква ı функцией toLowerCase() ошибочно определяется как не равная I, если только специально не используется 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Логичным и надежным решением для проверки равенства без учета регистра является использование API 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() — это позволяет сортировать строки с учетом локали.
Примитивные строки и строковые объекты
Обратите внимание, что JavaScript различает строковые объекты и примитивные строковые значения. (Это также справедливо для логических значений и чисел.)
Строковые литералы (разделённые двойными или одинарными кавычками) и строки, возвращаемые вызовами строк в неконструктивном контексте (т. е. вызванными без ключевого слова new), являются примитивными строками. В случаях, когда требуется вызвать метод для примитивной строки или выполнить поиск свойства, JavaScript автоматически оборачивает примитивную строку и вместо этого вызывает метод или выполняет поиск свойства объекта-обёртки.
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"По этим причинам код может перестать работать, если он встречает строковые объекты, хотя ожидает примитивную строку, хотя в целом авторам не нужно беспокоиться об этом различии.
Объект String всегда можно преобразовать в исходный аналог с помощью метода valueOf().
console.log(eval(s2.valueOf())); // returns the number 4
Приведение строки
Многие встроенные операции, ожидающие строки, сначала приводят свои аргументы к строкам (именно поэтому объекты String ведут себя как примитивные строки). Эти операции можно кратко описать следующим образом:
- Строки возвращаются как есть.
- Неопределенное становится “неопределенным”.
- null становится “пустым”.
- “Истинно” становится “истинно”. «Ложно» становится «ложно».
- Числа преобразуются по тому же алгоритму, что и toString(10).
- BigInts преобразуются по тому же алгоритму, что и toString(10).
- Символы вызывают ошибку TypeError.
- Сначала объекты преобразуются в примитивный тип путём вызова методов [Symbol.toPrimitive]() (с подсказкой “string”), toString() и valueOf() соответственно. Затем полученный примитив преобразуется в строку.
Существуют разные способы достижения примерно одного и того же эффекта в JavaScript.
- Буквально: `${x}` выполняет в точности те же действия по связыванию строк, которые описаны выше для встроенного выражения.
- Функция String(): String(x) использует тот же алгоритм для преобразования x, за исключением того, что Symbols не вызывает TypeError, а возвращает “Symbol(description)”, где description — это описание символа.
- Использование оператора +: "" + x приводит свой операнд к примитивному типу, а не к строке, и для некоторых объектов это приводит к совершенно иному поведению, чем обычное приведение к строке. Подробнее см. на странице справки.
В зависимости от вашего варианта использования вы можете захотеть использовать `${x}` (для имитации встроенного поведения) или String(x) (для обработки значений символов без возникновения ошибок), но вам не следует использовать “” + x. .
Символы UTF-16, кодовые точки Unicode и кластеры графем
Строки, по сути, представляют собой последовательность кодовых единиц UTF-16. В кодировке UTF-16 каждая кодовая единица имеет длину ровно 16 бит. Это означает, что в одной кодовой единице UTF-16 может быть максимум 216 или 65 536 возможных символов. Этот набор символов называется базовой многоязычной страницей (BMP) и включает в себя наиболее распространённые символы, такие как латинские, греческие, кириллические и многие восточноазиатские символы. Каждая кодовая единица может быть записана в виде строки с помощью \u, за которой следуют ровно четыре шестнадцатеричных цифры.
Однако весь набор символов Unicode значительно больше 65536. Дополнительные символы в UTF-16 хранятся в виде суррогатных пар, которые являются парами 16-битных кодовых единиц, представляющих один символ. Во избежание неоднозначности обе части пары должны находиться в диапазоне от 0xD800 до 0xDFFF, и эти кодовые единицы не используются для кодирования символов с одним кодом. (Точнее, начальные суррогаты, также называемые верхними суррогатными кодовыми единицами, имеют значения от 0xD800 до 0xDBFF, в то время как конечные суррогаты, также называемые нижними суррогатными кодовыми единицами, имеют значения от 0xDC00 до 0xDFFF, включая символ Unicode.) Символ, состоящий из одной или двух кодовых единиц UTF-16, также называется кодовой точкой Unicode. Любую кодовую точку Unicode можно записать в строке с помощью \u{xxxxxx}, где xxxxxx представляет от 1 до 6 шестнадцатеричных цифр.
“Один суррогат” — это 16-битная кодовая единица, соответствующая одному из следующих описаний:
- В диапазоне 0xD800–0xDBFF включительно (т. е. является ведущим суррогатом), но является последней кодовой единицей в строке, или следующая кодовая единица не является последним суррогатом.
- В диапазоне 0xDC00–0xDFFF включительно (т. е. последний суррогат), но первая кодовая единица в строке или предшествующая кодовая единица не является исходным суррогатом.
Одиночные суррогаты не представляют символы Unicode. Хотя большинство внутренних методов JavaScript обрабатывают их корректно, поскольку все они работают с кодовыми единицами UTF-16, одиночные суррогаты обычно не являются допустимыми значениями при взаимодействии с другими системами. Например, encodeURI() выдаёт ошибку URIE для одиночных суррогатов, поскольку для кодировки URI используется кодировка UTF-8, в которой нет кодировки для одиночных суррогатов. Строки, не содержащие одиночных суррогатов, называются правильно сформированными строками и могут безопасно использоваться с функциями, не работающими с UTF-16 (например, encodeURI() или TextEncoder ). Вы можете проверить правильность строки с помощью метода isWellFormed() или очистить одиночные суррогаты с помощью метода toWellFormed().
Над символами Unicode расположена определённая последовательность символов Unicode, которую следует рассматривать как визуальную единицу, известную как графический кластер. Наиболее распространённый случай — смайлики: многие смайлики, имеющие широкий спектр вариаций, фактически состоят из нескольких эмодзи, обычно с символом (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.
Статические методы
String.fromCharCode()
Возвращает строку, созданную с использованием указанной последовательности значений Unicode.
String.fromCodePoint()
Возвращает строку, созданную с использованием указанной последовательности кодовых точек.
Строка.raw()
Возвращает строку, созданную из необработанной строки шаблона.
Примеры свойств
Эти свойства определены в String.prototype и являются общими для всех экземпляров String.
Строка.прототип.конструктор
Функция-конструктор, создающая объект экземпляра. Для строковых экземпляров начальным значением является конструктор строки.
Эти функции специфичны для каждого экземпляра строки.
длина
Отражает длину строки. Только для чтения.
Методы выборки
Строка.прототип.at()
Возвращает символ (ровно одну кодовую единицу UTF-16) в указанном индексе. Принимает отрицательные целые числа, начиная с последнего символа строки.
String.prototype.charAt()
Возвращает символ (ровно одну кодовую единицу UTF-16) в указанном индексе.
String.prototype.charCodeAt()
Возвращает число, являющееся значением кодовой единицы UTF-16 по указанному индексу.
String.prototype.codePointAt()
Возвращает неотрицательное целое число, представляющее собой значение кодовой точки в кодировке UTF-16, начиная с указанной позы.
Строка.прототип.concat()
Текст объединяет две (или более) строки и возвращает новую строку.
String.prototype.endsWith()
Определяет, заканчивается ли строка символами строки searchString.
String.prototype.includes()
Определяет, содержит ли вызывающая строка SearchString.
Строка.прототип.indexOf()
Возвращает индекс первого вхождения searchValue в данной строке или -1, если не найдено.
String.prototype.isWellFormed()
Возвращает логическое значение, указывающее, содержит ли эта строка единичные замены.
String.prototype.lastIndexOf()
Возвращает индекс последнего вхождения searchValue в данной строке или -1, если не найдено.
String.prototype.localeCompare()
Возвращает число, указывающее, находится ли строка, на которую ссылается compareString, до, после или эквивалентна заданной строке в порядке сортировки.
Строка.прототип.match()
Он используется для сопоставления регулярного выражения regexp со строкой.
String.prototype.matchAll()
Возвращает итератор всех совпадений регулярного выражения.
String.prototype.normalize()
Нормализованная форма Unicode возвращает значение вызывающей строки.
String.prototype.padEnd()
Объединяет текущую строку с конца со строкой и возвращает новую строку длиной targetLength.
String.prototype.padStart()
Дополняет текущую строку с начала заданной строкой и возвращает новую строку длины targetLength.
Строка.прототип.повторить()
Возвращает строку, состоящую из элементов объекта, подсчитанных раз.
Строка.прототип.replace()
SearchFor используется для замены элементов с помощью replaceWith. searchFor может быть строкой или регулярным выражением, а replaceWith может быть строкой или функцией.
String.prototype.replaceAll()
SearchFor используется для замены всех вхождений replaceWith. searchFor может быть строкой или регулярным выражением, а replaceWith может быть строкой или функцией.
Строка.прототип.поиск()
Поиск соответствия между регулярным выражением regexp и вызывающей строкой.
Строка.прототип.срез()
Извлекает часть строки и возвращает новую строку.
Строка.прототип.split()
Возвращает массив строк, заполненный путем разбиения вызывающей строки на подстроки строки sep.
String.prototype.startsWith()
Определяет, начинается ли вызывающая строка с символов из строки searchString.
String.prototype.substr() устарел
Возвращает часть строки, начинающуюся с указанного индекса и продолжающуюся указанным количеством символов.
Строка.прототип.подстрока()
Возвращает новую строку, содержащую символы вызывающей строки из указанного индекса (или между ними).
String.prototype.toLocaleLowerCase()
Символы в строке преобразуются в строчные с учетом текущей локали.
Для большинства языков это возвращает то же состояние, что и toLowerCase().
String.prototype.toLocaleUpperCase()
Символы в строке преобразуются в верхний регистр с учетом текущей локали.
Для большинства языков это возвращает то же состояние, что и toUpperCase().
String.prototype.toLowerCase()
Возвращает значение вызывающей строки, преобразованное в нижний регистр.
String.prototype.toString()
Возвращает строку, представляющую указанный объект. Переопределяет метод Object.prototype.toString().
String.prototype.toUpperCase()
Возвращает значение вызывающей строки, преобразованное в верхний регистр.
String.prototype.toWellFormed()
Возвращает строку, в которой все отдельные вхождения этой строки заменены заменяющим символом Unicode U+FFFD.
Строка.прототип.trim()
Удаляет пробелы в начале и конце строки.
String.prototype.trimEnd()
Обрезает конец строки пробелом.
Строка.прототип.trimStart()
Удаляет пробелы в начале строки.
Строка.прототип.значение()
Возвращает начальное значение указанного объекта. Переопределяет метод Object.prototype.valueOf().
Строка.прототип[Символ.итератор]()
Возвращает новый объект итератора, который выполняет итерацию по кодовым точкам строкового значения, возвращая каждую кодовую точку как строковое значение.









