diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
commit | 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 (patch) | |
tree | a9ef8ac1e1b8fe4207b6d64d3841bfb8990b6fd0 /files/uk/web/javascript/reference/global_objects/string/charat/index.html | |
parent | 074785cea106179cb3305637055ab0a009ca74f2 (diff) | |
download | translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.gz translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.bz2 translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.zip |
initial commit
Diffstat (limited to 'files/uk/web/javascript/reference/global_objects/string/charat/index.html')
-rw-r--r-- | files/uk/web/javascript/reference/global_objects/string/charat/index.html | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/files/uk/web/javascript/reference/global_objects/string/charat/index.html b/files/uk/web/javascript/reference/global_objects/string/charat/index.html new file mode 100644 index 0000000000..004400895c --- /dev/null +++ b/files/uk/web/javascript/reference/global_objects/string/charat/index.html @@ -0,0 +1,316 @@ +--- +title: String.prototype.charAt() +slug: Web/JavaScript/Reference/Global_Objects/String/charAt +tags: + - JavaScript + - Method + - Prototype + - String + - Довідка +translation_of: Web/JavaScript/Reference/Global_Objects/String/charAt +--- +<div>{{JSRef}}</div> + +<p><span class="seoSummary">Метод <strong><code>charAt()</code></strong> створює і вертає підрядок, що міститиме лише один символ (кодова одиниця UTF-16), розташований у рядку із зазначеним зсувом.</span></p> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox"><em>str</em>.charAt(<em>index</em>)</pre> + +<h3 id="Параметри">Параметри</h3> + +<dl> + <dt><code>index</code></dt> + <dd>Індекс символа у рядку, ціле число від <code>0</code> до <code>str.length - 1</code>. Якщо не зазначено (метод викликано без аргументів), метод повертає перший символ рядка.</dd> +</dl> + +<h3 id="Вертає">Вертає</h3> + +<p>Підрядок з одного символа (одна кодова одиниця UTF-16) отриманого за вказаним індексом, або порожній рядок, якщо <code>index</code> вказує за межі рядка (менше <code>0</code> чи понад <code>str.length - 1</code>).</p> + +<h2 id="Опис">Опис</h2> + +<p>Кожен символ рядка має індекс, що зростає зліва направо. Лік починається від нуля, тож перший символ має індекс <code>0</code>, а останній — <code>str.length - 1</code>. Якщо зазначено індекс, що за ці межі виходить, метод <code>chartAt()</code> вертає порожній рядок.</p> + +<p>Якщо індекс не зазначено для метода <code>charAt()</code>, буде задіяно типове значення <code>0</code>.</p> + +<h2 id="Приклади">Приклади</h2> + +<h3 id="Виведення_різних_символів_рядка">Виведення різних символів рядка</h3> + +<p>Цей приклад дістає та виводить до консолі різні символи рядка <code>«Хай йому грець»</code>:</p> + +<pre class="brush: js">var str = 'Хай йому грець'; + +// Індекс не зазначено, буде неявно задіяно значення 0 +console.log(str.charAt()); // виводить "Х" + +console.log(str.charAt(0)); // виводить "Х" +console.log(str.charAt(1)); // виводить "а" +console.log(str.charAt(2)); // виводить "й" + +console.log(str.charAt(-1)); // виводить "" +console.log(str.charAt(99)); // виводить "" +</pre> + +<h3 id="Отримання_цілого_символа">Отримання цілого символа</h3> + +<p>Позаяк деякі символи в UTF-16 подаються двома кодовими одиницями, слід зважати на те, що метод <code>charAt()</code> дістає їх з рядка нарізно, а отже задля отримання цілого символа доведеться їх об'єднати.</p> + +<p>Наведений нижче код призначено для послідовної обробки рядків, що можуть містити такі складені символи (не належать до <abbr title="Basic Multilingual Plane (BMP)">Основної Багатомовної Площини (ОБП)</abbr> Unicode):</p> + +<pre class="brush: js">// Символи поза ОБП можна було б вжити безпосередньо +var str = 'A \uD87E\uDC04 Z'; + +for (var i = 0, chr; i < str.length; i++) { + // Просто додайте цю перевірку на початку кожного циклу з перебору символів + // і завжди матимете складені символи повністю, а не половини складеного + // символа нарізно. + if ((chr = getWholeChar(str, i)) === false) { + continue; + } + + console.log(chr); +} + +function getWholeChar(str, i) { + var code = str.charCodeAt(i); + + // Значення зсуву «i» за межами рядка + if (Number.isNaN(code)) { + return ''; + } + if (code < 0xD800 || code > 0xDFFF) { + return str.charAt(i); + } + + // Старша половина (можна замінити друге значення на 0xDB7F й тлумачити + // «старші половини приватного вжитку» як окремі символи). + if (0xD800 <= code && code <= 0xDBFF) { + if (str.length <= (i + 1)) { + throw 'High surrogate without following low surrogate'; + } + + var next = str.charCodeAt(i + 1); + if (0xDC00 > next || next > 0xDFFF) { + throw 'High surrogate without following low surrogate'; + } + return str.charAt(i) + str.charAt(i + 1); + } + + // Молодша половина (0xDC00 <= code && code <= 0xDFFF) + if (i === 0) { + throw 'Low surrogate without preceding high surrogate'; + } + var prev = str.charCodeAt(i - 1); + + // Можна замінити друге значення на 0xDB7F й тлумачити + // «старші половини приватного вжитку» як окремі символи. + if (0xD800 > prev || prev > 0xDBFF) { + throw 'Low surrogate without preceding high surrogate'; + } + + // Молодшу половину було оброблено разом із старшою, тож тепер + // ми її пропускаємо. + return false; +} +</pre> + +<p>У середовищі ECMAScript 2016, що підтримує присвоєння {{jsxref("Operators/Деструктуризація", "деструктурованням")}}, можна трохи поліпшити легкочитність коду, повертаючи з функції також оновлене (якщо останній символ був складений) значення зсуву:</p> + +<pre class="brush: js">// Символи поза ОБП можна було б вжити безпосередньо +var str = 'A\uD87E\uDC04Z'; +for (var i = 0, chr; i < str.length; i++) { + [chr, i] = getWholeCharAndI(str, i); + // Просто додайте цей виклик на початку кожного циклу з перебору символів + // і завжди матимете складені символи повністю, а не половини складеного + // символа нарізно. + // Значення «i» буде оновлено, якщо метод натрапить на складений символ. + + console.log(chr); +} + +function getWholeCharAndI(str, i) { + var code = str.charCodeAt(i); + + // Значення зсуву «i» за межами рядка + if (Number.isNaN(code)) { + return ['', i]; + } + if (code < 0xD800 || code > 0xDFFF) { + / / Звичайний символ, просто лишаємо все як є. + return [str.charAt(i), i]; + } + + // Старша половина (можна замінити друге значення на 0xDB7F й тлумачити + // «старші половини приватного вжитку» як окремі символи). + if (0xD800 <= code && code <= 0xDBFF) { + if (str.length <= (i + 1)) { + throw 'High surrogate without following low surrogate'; + } + var next = str.charCodeAt(i + 1); + if (0xDC00 > next || next > 0xDFFF) { + throw 'High surrogate without following low surrogate'; + } + + // Зібрати складений символ докупи й повернути збільшений зсув + return [str.charAt(i) + str.charAt(i + 1), i + 1]; + } + + // Low surrogate (0xDC00 <= code && code <= 0xDFFF) + if (i === 0) { + throw 'Low surrogate without preceding high surrogate'; + } + var prev = str.charCodeAt(i - 1); + + // Можна замінити друге значення на 0xDB7F й тлумачити + // «старші половини приватного вжитку» як окремі символи. + if (0xD800 > prev || prev > 0xDBFF) { + throw 'Low surrogate without preceding high surrogate'; + } + + // Повернути натомість наступний символ й повернути збільшений зсув + return [str.charAt(i + 1), i + 1]; +} +</pre> + +<p>Також можна навести більш витончене рішення, хоча дещо менш гнучке:</p> + +<pre class="brush: js">// Просто перебираємо символи рядка за допомогою forEachChar() +forEachChar('A\uD87E\uDC04Z', function(c) { + console.log(c); +}); + +function forEachChar(string, predicate) { + for (var i = 0; i < string.length; i++) { + var code = string.charCodeAt(i); + var value; + + // Звичайний символ, просто лишаємо як є. + if (code < 0xD800 || code > 0xDFFF) { + value = string.charAt(i); + } else { + // Старша половина (можна замінити друге значення на 0xDB7F й тлумачити + // «старші половини приватного вжитку» як окремі символи). + if (0xD800 <= code && code <= 0xDBFF) { + if (string.length <= (i + 1)) { + throw 'High surrogate without following low surrogate'; + } + + var next = string.charCodeAt(i + 1); + if (0xDC00 > next || next > 0xDFFF) { + throw 'High surrogate without following low surrogate'; + } + + value = string.charAt(i) + string.charAt(i + 1); + i++; + } else { + // Молодша половина (0xDC00 <= code && code <= 0xDFFF) + throw 'Low surrogate without preceding high surrogate'; + } + } + + // Перебір можна перервати, повернувши з функції-присудка значення false + if (false === predicate.call(string, value)) { + return; + } + } +} +</pre> + +<h3 id="Виправлений_charAt()_з_урахуванням_складених_символів">Виправлений <code>charAt()</code> з урахуванням складених символів</h3> + +<p>Приклад нижче наводить функцію <code>fixedCharAt()</code>, яка не лише злучає половинки складених символів, а ще й змінює індексацію символів таким чином, що <code>index</code> позначає порядковий номер (лік від нуля, як завжди) не кодової одиниці (як для звичайного <code>charAt()</code>), а саме повного символа.</p> + +<p>Втім, слід зважати, що це рішення є вкрай неоптимальним, якщо користувати його для перебору всього рядка:</p> + +<pre class="brush: js">function fixedCharAt(string, index) { + var isExpectingLowSurrogate = false; + var charIndex = 0; + var i = 0; + + // За межами рядка. + if (index < 0 || index >= string.length) { + return ''; + } + + while (i < string.length && charIndex < index) { + if (isHighSurrogateAt(string, i) && isLowSurrogateAt(string, i + 1)) { + i++; + } + + i++; + charIndex++; + } + + if (i < string.length) { + if (isHighSurrogateAt(string, i) && isLowSurrogateAt(string, i + 1)) { + return string.charAt(i) + string.charAt(i + 1); + } else { + return string.charAt(i); + } + } + + return ''; +} + +function isHighSurrogateAt(string, index) { + var code = string.charCodeAt(index); + return 0xD800 <= code && code <= 0xDBFF; +} + +function isLowSurrogateAt(string, index) { + var code = string.charCodeAt(index); + return 0xDC00 <= code && code <= 0xDFFF; +} +</pre> + +<h2 id="Специфікації">Специфікації</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Специфікація</th> + <th scope="col">Статус</th> + <th scope="col">Коментар</th> + </tr> + <tr> + <td>{{SpecName('ES1')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Початкова виознака.</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-15.5.4.4', 'String.prototype.charAt')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-string.prototype.charat', 'String.prototype.charAt')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-string.prototype.charat', 'String.prototype.charAt')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Підтримка_веб-переглядачами">Підтримка веб-переглядачами</h2> + +<div class="hidden">Таблиця сумісності на цій сторінці створена зі структурованих даних. Якщо ви хочете долучитися до розробки цих даних, пропонуйте нам свої pull request до репозиторію <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</div> + +<p>{{Compat("javascript.builtins.String.charAt")}}</p> + +<h2 id="Див._також">Див. також</h2> + +<ul> + <li>{{jsxref("String.prototype.indexOf()")}}</li> + <li>{{jsxref("String.prototype.lastIndexOf()")}}</li> + <li>{{jsxref("String.prototype.charCodeAt()")}}</li> + <li>{{jsxref("String.prototype.codePointAt()")}}</li> + <li>{{jsxref("String.prototype.split()")}}</li> + <li>{{jsxref("String.fromCodePoint()")}}</li> + <li><a href="https://mathiasbynens.be/notes/javascript-unicode">Негаразди з Unicode у JavaScript — Mathias Bynens</a></li> +</ul> |