From 85db3f6727101af1467efbfa01c4f396b72c6327 Mon Sep 17 00:00:00 2001 From: Mykola Sopiha Date: Wed, 25 Aug 2021 23:10:28 +0300 Subject: [PATCH 1/5] iterables --- 1-js/05-data-types/06-iterable/article.md | 48 +++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 37d7e31e5..b5cb050ac 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -1,20 +1,20 @@ -# Iterables +# Ітеративні об’єкти -*Iterable* objects are a generalization of arrays. That's a concept that allows us to make any object useable in a `for..of` loop. +*Ітеративні* об’єкти є узагальненням масивів. Це концепція, яка дозволяє нам зробити будь-який об’єкт придатним для використання в циклі `for..of`. -Of course, Arrays are iterable. But there are many other built-in objects, that are iterable as well. For instance, strings are also iterable. +Звичайно, по масивам можна ітеруватися. Але є багато інших вбудованих об’єктів, які також можна ітерувати. Наприклад, рядки також можна ітерувати. -If an object isn't technically an array, but represents a collection (list, set) of something, then `for..of` is a great syntax to loop over it, so let's see how to make it work. +Якщо об’єкт технічно не є масивом, а представляє колекцію (list, set) чогось, то `for..of` - чудовий синтаксис для його обходу, тому давайте подивимося, як змусити його працювати. ## Symbol.iterator -We can easily grasp the concept of iterables by making one of our own. +Ми можемо легко зрозуміти концепцію ітеративних об’єктіва, зробивши її власноруч. -For instance, we have an object that is not an array, but looks suitable for `for..of`. +Наприклад, у нас є об’єкт, який не є масивом, але виглядає придатним для `for..of`. -Like a `range` object that represents an interval of numbers: +Як, наприклад, об’єкт `range`, який представляє інтервал чисел: ```js let range = { @@ -22,18 +22,18 @@ let range = { to: 5 }; -// We want the for..of to work: +// Ми хочемо, щоб for..of працював: // for(let num of range) ... num=1,2,3,4,5 ``` -To make the `range` object iterable (and thus let `for..of` work) we need to add a method to the object named `Symbol.iterator` (a special built-in symbol just for that). +Щоб зробити об'єкт `range` ітерабельним (і таким чином дозволити `for..of` працювати), нам потрібно додати метод до об’єкта з назвою `Symbol.iterator` (спеціальний вбудований символ саме для цього). -1. When `for..of` starts, it calls that method once (or errors if not found). The method must return an *iterator* -- an object with the method `next`. -2. Onward, `for..of` works *only with that returned object*. -3. When `for..of` wants the next value, it calls `next()` on that object. -4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the iteration is finished, otherwise `value` is the next value. +1. Коли `for..of` запускається, він викликає цей метод один раз (або викликає помилку, якщо цей метод не знайдено). Метод повинен повернути *ітератор* -- об’єкт з методом `next`. +2. Далі `for..of` працює *лише з поверненим об’єктом*. +3. Коли `for..of` хоче отримати наступне значення, він викликає `next()` на цьому об’єкті. +4. Результат `next()` повинен мати вигляд `{done: Boolean, value: any}`, де `done=true` означає, що ітерація завершена, інакше `value` -- це наступне значення. -Here's the full implementation for `range` with remarks: +Ось повна реалізація об’єкту `range` із зауваженнями: ```js run let range = { @@ -41,18 +41,18 @@ let range = { to: 5 }; -// 1. call to for..of initially calls this +// 1. виклик for..of спочатку викликає цю функцію range[Symbol.iterator] = function() { - // ...it returns the iterator object: - // 2. Onward, for..of works only with this iterator, asking it for next values + // ...вона повертає об’єкт ітератора: + // 2. Далі, for..of працює тільки з цим ітератором, запитуючи у нього наступні значення return { current: this.from, last: this.to, - // 3. next() is called on each iteration by the for..of loop + // 3. next() викликається на кожній ітерації циклом for..of next() { - // 4. it should return the value as an object {done:.., value :...} + // 4. він повинен повертати значення як об’єкт {done:.., value :...} if (this.current <= this.last) { return { done: false, value: this.current++ }; } else { @@ -62,16 +62,16 @@ range[Symbol.iterator] = function() { }; }; -// now it works! +// тепер це працює! for (let num of range) { - alert(num); // 1, then 2, 3, 4, 5 + alert(num); // 1, потім 2, 3, 4, 5 } ``` -Please note the core feature of iterables: separation of concerns. +Будь ласка, зверніть увагу на основну особливість ітеративних об’єктів: розділення проблем. -- The `range` itself does not have the `next()` method. -- Instead, another object, a so-called "iterator" is created by the call to `range[Symbol.iterator]()`, and its `next()` generates values for the iteration. +- Сам `range` не має методу `next()`. +- Натомість інший об’єкт, так званий "ітератор", створюється за допомогою виклику `range[Symbol.iterator]()`, а його `next()` генерує значення для ітерації. So, the iterator object is separate from the object it iterates over. From 7798632ae174015856ca29ac40e4548cd268e431 Mon Sep 17 00:00:00 2001 From: Mykola Sopiha Date: Sat, 28 Aug 2021 14:14:12 +0300 Subject: [PATCH 2/5] iterables --- 1-js/05-data-types/06-iterable/article.md | 74 +++++++++++------------ 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index b5cb050ac..b61453b86 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -26,7 +26,7 @@ let range = { // for(let num of range) ... num=1,2,3,4,5 ``` -Щоб зробити об'єкт `range` ітерабельним (і таким чином дозволити `for..of` працювати), нам потрібно додати метод до об’єкта з назвою `Symbol.iterator` (спеціальний вбудований символ саме для цього). +Щоб зробити об’єкт `range` ітерабельним (і таким чином дозволити `for..of` працювати), нам потрібно додати метод до об’єкта з назвою `Symbol.iterator` (спеціальний вбудований символ саме для цього). 1. Коли `for..of` запускається, він викликає цей метод один раз (або викликає помилку, якщо цей метод не знайдено). Метод повинен повернути *ітератор* -- об’єкт з методом `next`. 2. Далі `for..of` працює *лише з поверненим об’єктом*. @@ -73,11 +73,11 @@ for (let num of range) { - Сам `range` не має методу `next()`. - Натомість інший об’єкт, так званий "ітератор", створюється за допомогою виклику `range[Symbol.iterator]()`, а його `next()` генерує значення для ітерації. -So, the iterator object is separate from the object it iterates over. +Отже, об’єкт, що ітерує відокремлений від об’єкта, який він ітерує. -Technically, we may merge them and use `range` itself as the iterator to make the code simpler. +Технічно, ми можемо об’єднати їх і використовувати `range` в якості ітератора, щоб зробити код більш простим. -Like this: +Подібно до цього: ```js run let range = { @@ -99,55 +99,54 @@ let range = { }; for (let num of range) { - alert(num); // 1, then 2, 3, 4, 5 + alert(num); // 1, тоді 2, 3, 4, 5 } ``` -Now `range[Symbol.iterator]()` returns the `range` object itself: it has the necessary `next()` method and remembers the current iteration progress in `this.current`. Shorter? Yes. And sometimes that's fine too. +Тепер `range[Symbol.iterator]()` повертає сам об'єкт `range`: він має необхідний `next()` метод і пам'ятає поточну ітерацію прогресу в `this.current`. Коротше? Так. А іноді це також добре. -The downside is that now it's impossible to have two `for..of` loops running over the object simultaneously: they'll share the iteration state, because there's only one iterator -- the object itself. But two parallel for-ofs is a rare thing, even in async scenarios. +Недоліком є те, що тепер неможливо мати два `for..of` цикли паралельно для проходження через об’єкт: вони будуть ділити ітераційний стан, тому що є тільки один ітератор -- сам об'єкт. Але два параллельних for-of це рідкісний випадок, навіть у асинхронізованих сценаріях. ```smart header="Infinite iterators" -Infinite iterators are also possible. For instance, the `range` becomes infinite for `range.to = Infinity`. Or we can make an iterable object that generates an infinite sequence of pseudorandom numbers. Also can be useful. +Також можливі нескінченні ітератори. Наприклад, `range` стає нескінченним для `range.to = Infinity`. Або ми можемо зробити ітерований об'єкт, який генерує нескінченну послідовність псевдорандомних чисел. Це також може бути корисним. +Немає обмежень на `next`, він може повертати все більше і більше значень, це нормально. -There are no limitations on `next`, it can return more and more values, that's normal. - -Of course, the `for..of` loop over such an iterable would be endless. But we can always stop it using `break`. +Звичайно, `for..of` цикли через такий об’єкт буде безкінечним. Але ми завжди можемо зупинити його за допомогою `break`. ``` -## String is iterable +## Рядок є ітерованим -Arrays and strings are most widely used built-in iterables. +Масиви та рядки найбільш широко використовуються вбудовані ітератори. -For a string, `for..of` loops over its characters: +Для рядка, `for..of` цикл проходить по символам: ```js run for (let char of "test") { - // triggers 4 times: once for each character - alert( char ); // t, then e, then s, then t + // викликається 4 рази: один раз для кожного символу + alert( char ); // t, потім e, потім s, потім t } ``` -And it works correctly with surrogate pairs! +І це правильно працює з сурогатними парами! ```js run let str = '𝒳😂'; for (let char of str) { - alert( char ); // 𝒳, and then 😂 + alert( char ); // 𝒳, і потім 😂 } ``` -## Calling an iterator explicitly +## Виклик ітератора явно -For deeper understanding, let's see how to use an iterator explicitly. +Для більш глибокого розуміння, давайте подивимося, як явно використовувати ітератор. -We'll iterate over a string in exactly the same way as `for..of`, but with direct calls. This code creates a string iterator and gets values from it "manually": +Ми будемо ітерувати рядок точно так само, як для `for..of`, але з прямими викликами. Цей код створює ітератор рядка і отримує значення від нього "вручну": ```js run -let str = "Hello"; +let str = "Привіт"; -// does the same as +// робить те ж саме, як // for (let char of str) alert(char); *!* @@ -157,43 +156,42 @@ let iterator = str[Symbol.iterator](); while (true) { let result = iterator.next(); if (result.done) break; - alert(result.value); // outputs characters one by one + alert(result.value); // виводить символи один за одним } ``` -That is rarely needed, but gives us more control over the process than `for..of`. For instance, we can split the iteration process: iterate a bit, then stop, do something else, and then resume later. - -## Iterables and array-likes [#array-like] +Це рідко потрібно, але дає нам більше контролю над процесом, ніж `для ..of`. Наприклад, ми можемо розділити процес ітерації: трохи ітерувати, а потім зупинитися, зробити щось інше, а потім відновити пізніше. -Two official terms look similar, but are very different. Please make sure you understand them well to avoid the confusion. +## Ітеровані об’єкти та псевдомасиви [#array-like] -- *Iterables* are objects that implement the `Symbol.iterator` method, as described above. -- *Array-likes* are objects that have indexes and `length`, so they look like arrays. +Ці два офіційних терміни виглядають подібними, але дуже різні. Будь ласка, переконайтеся, що ви добре розумієте їх, щоб уникнути плутанини. -When we use JavaScript for practical tasks in a browser or any other environment, we may meet objects that are iterables or array-likes, or both. +- *Ітеровані* -- це об'єкти, які реалізують метод `Symbol.iterator`, як описано вище. +- *Псевдомасиви* -- це об'єкти, які мають індекси та `length`, тому вони виглядають як масиви. -For instance, strings are both iterable (`for..of` works on them) and array-like (they have numeric indexes and `length`). +Коли ми використовуємо JavaScript для практичних завдань у браузері або будь-якому іншому середовищі, ми можемо зустріти об'єкти, які є ітерованими або масивами, або обома. +Наприклад, рядки є ітерованими об’єктами (`for..of` працює на них) та псевдомасивами (у них є числові індекси та `length`). -But an iterable may be not array-like. And vice versa an array-like may be not iterable. +Але ітерований об’єкт може не бути масивом. І навпаки, псевдомасив може бути не ітерованим об’єктом. -For example, the `range` in the example above is iterable, but not array-like, because it does not have indexed properties and `length`. +Наприклад, `range` у прикладі вище є ітерованим об’єктом, але не масивом, тому що він не має індексованих властивостей та `length`. -And here's the object that is array-like, but not iterable: +І ось об'єкт, який є псевдомасивом, але не ітерованим об’єктом: ```js run -let arrayLike = { // has indexes and length => array-like +let arrayLike = { // має індекси та length => псевдомасив 0: "Hello", 1: "World", length: 2 }; *!* -// Error (no Symbol.iterator) +// Error (немає Symbol.iterator) for (let item of arrayLike) {} */!* ``` -Both iterables and array-likes are usually *not arrays*, they don't have `push`, `pop` etc. That's rather inconvenient if we have such an object and want to work with it as with an array. E.g. we would like to work with `range` using array methods. How to achieve that? +Обидва, ітерований об’єкт та псевдомасив, як правило є *не масивами*, вони не мають `push`,` pop` та ін. Це досить незручно, якщо у нас є такий об’єкт і ми хочемо працювати з ним як з масивом. НаприкладМи хотіли б працювати з `angy` за допомогою методів масиву. Як цього досягти? ## Array.from From eaa90c84cf638d90cc50ee2bd5dc29ccf0acead9 Mon Sep 17 00:00:00 2001 From: Mykola Sopiha Date: Sat, 4 Sep 2021 03:07:14 +0300 Subject: [PATCH 3/5] iterables --- 1-js/05-data-types/06-iterable/article.md | 67 ++++++++++++----------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index b61453b86..3995432cf 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -160,7 +160,7 @@ while (true) { } ``` -Це рідко потрібно, але дає нам більше контролю над процесом, ніж `для ..of`. Наприклад, ми можемо розділити процес ітерації: трохи ітерувати, а потім зупинитися, зробити щось інше, а потім відновити пізніше. +Це рідко потрібно, але дає нам більше контролю над процесом, ніж `for ..of`. Наприклад, ми можемо розділити процес ітерації: трохи ітерувати, а потім зупинитися, зробити щось інше, а потім відновити пізніше. ## Ітеровані об’єкти та псевдомасиви [#array-like] @@ -186,7 +186,7 @@ let arrayLike = { // має індекси та length => псевдомасив }; *!* -// Error (немає Symbol.iterator) +// Помилка (немає Symbol.iterator) for (let item of arrayLike) {} */!* ``` @@ -195,57 +195,57 @@ for (let item of arrayLike) {} ## Array.from -There's a universal method [Array.from](mdn:js/Array/from) that takes an iterable or array-like value and makes a "real" `Array` from it. Then we can call array methods on it. +Існує універсальний метод [Array.from](mdn:js/Array/from), який приймає ітерований об’єкт або псевдомасив і робить з нього "справжній" масив. Тоді ми можемо викликати на ньому методи масиву. -For instance: +Наприклад: ```js run let arrayLike = { - 0: "Hello", - 1: "World", + 0: "Привіт", + 1: "Світ", length: 2 }; *!* let arr = Array.from(arrayLike); // (*) */!* -alert(arr.pop()); // World (method works) +alert(arr.pop()); // Світ (метод працює) ``` -`Array.from` at the line `(*)` takes the object, examines it for being an iterable or array-like, then makes a new array and copies all items to it. +`Array.from` у рядку `(*)` бере об'єкт, перевіряє його на ітерабельність або те, що це псевдомасив, потім створює новий масив і копіює до нього всі елементи. -The same happens for an iterable: +Те ж саме відбувається і з ітерованим об’єктом: ```js -// assuming that range is taken from the example above +// припустимо, що діапазон взятий з наведеного вище прикладу let arr = Array.from(range); alert(arr); // 1,2,3,4,5 (array toString conversion works) ``` -The full syntax for `Array.from` also allows us to provide an optional "mapping" function: +Повний синтаксис для `Array.from` також дозволяє нам надати додаткову функцію "трансформації": ```js Array.from(obj[, mapFn, thisArg]) ``` The optional second argument `mapFn` can be a function that will be applied to each element before adding it to the array, and `thisArg` allows us to set `this` for it. -For instance: +Наприклад: ```js -// assuming that range is taken from the example above +// припустимо, що діапазон взятий з наведеного вище прикладу -// square each number +// порахуємо квадрат кожного числа let arr = Array.from(range, num => num * num); alert(arr); // 1,4,9,16,25 ``` -Here we use `Array.from` to turn a string into an array of characters: +Тут ми використовуємо `Array.from`, щоб перетворити рядок у масив символів: ```js run let str = '𝒳😂'; -// splits str into array of characters +// розіб’ємо рядок на масив символів let chars = Array.from(str); alert(chars[0]); // 𝒳 @@ -253,14 +253,14 @@ alert(chars[1]); // 😂 alert(chars.length); // 2 ``` -Unlike `str.split`, it relies on the iterable nature of the string and so, just like `for..of`, correctly works with surrogate pairs. +На відміну від `str.split`, він спирається на ітерабельний характер рядка і тому, так само, як `for..of`, коректно працює з сурогатними парами. -Technically here it does the same as: +Технічно тут це відбувається так само, як: ```js run let str = '𝒳😂'; -let chars = []; // Array.from internally does the same loop +let chars = []; // Array.from внутрішньо робить цей самий цикл for (let char of str) { chars.push(char); } @@ -268,9 +268,9 @@ for (let char of str) { alert(chars); ``` -...But it is shorter. +...Але це коротше. -We can even build surrogate-aware `slice` on it: +Ми навіть можемо побудувати на ньому `slice`, що підтримує сутогатні пари: ```js run function slice(str, start, end) { @@ -281,25 +281,26 @@ let str = '𝒳😂𩷶'; alert( slice(str, 1, 3) ); // 😂𩷶 -// the native method does not support surrogate pairs -alert( str.slice(1, 3) ); // garbage (two pieces from different surrogate pairs) +// нативний метод не підтримує сурогатні пари +alert( str.slice(1, 3) ); // сміття (дві частини з різних сурогатних пар) ``` -## Summary +## Підсумки -Objects that can be used in `for..of` are called *iterable*. +Об'єкти, які можна використовуватися у `for..of`, називаються *ітерованими*. -- Technically, iterables must implement the method named `Symbol.iterator`. - - The result of `obj[Symbol.iterator]()` is called an *iterator*. It handles further iteration process. +- Технічно ітеровані об’єкти повинні реалізовувати метод з назвою `Symbol.iterator`. + - Результат `obj[Symbol.iterator]()` називається *ітератором*. Він забезпечує подальший процес ітерації. - An iterator must have the method named `next()` that returns an object `{done: Boolean, value: any}`, here `done:true` denotes the end of the iteration process, otherwise the `value` is the next value. -- The `Symbol.iterator` method is called automatically by `for..of`, but we also can do it directly. -- Built-in iterables like strings or arrays, also implement `Symbol.iterator`. -- String iterator knows about surrogate pairs. + - Ітератор повинен мати метод з назвою `next()`, який повертає об'єкт `{done: Boolean, value: any}`, де `done: true` означає кінець процесу ітерації, інакше `value` є наступним значенням. +- Метод `Symbol.iterator` автоматично викликається `for..of`, але ми також можемо це зробити безпосередньо. +- Вбудовані ітеровані об’єкти, такі як рядки або масиви, також реалізують `Symbol.iterator`. +- Рядковий ітератор знає про сурогатні пари. -Objects that have indexed properties and `length` are called *array-like*. Such objects may also have other properties and methods, but lack the built-in methods of arrays. +Об'єкти, які мають індексовані властивості та `length`, називаються *псевдомасивами*. Такі об’єкти також можуть мати інші властивості та методи, але не мають вбудованих методів масивів. -If we look inside the specification -- we'll see that most built-in methods assume that they work with iterables or array-likes instead of "real" arrays, because that's more abstract. +Якщо ми заглянемо в специфікацію -- ми побачимо, що більшість вбудованих методів припускають, що вони працюють з ітерованими об’єктами або псевдомасивами замість "реальних" масивів, тому що це більш абстрактно. -`Array.from(obj[, mapFn, thisArg])` makes a real `Array` from an iterable or array-like `obj`, and we can then use array methods on it. The optional arguments `mapFn` and `thisArg` allow us to apply a function to each item. +`Array.from(obj[, mapFn, thisArg])` створює справжній `Array` з ітерованого об’єкту або псевдомасиву `obj`, і тоді ми можемо використовувати на ньому методи масиву. Необов’язкові аргументи `mapFn` та` thisArg` дозволяють нам застосовувати функції до кожного елемента. From fb1a96f5a59085f756c7a59a2fbc32e9bf4aee88 Mon Sep 17 00:00:00 2001 From: Mykola Sopiha Date: Sat, 4 Sep 2021 15:51:44 +0300 Subject: [PATCH 4/5] iterables --- 1-js/05-data-types/06-iterable/article.md | 38 +++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index 3995432cf..a91866186 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -3,14 +3,14 @@ *Ітеративні* об’єкти є узагальненням масивів. Це концепція, яка дозволяє нам зробити будь-який об’єкт придатним для використання в циклі `for..of`. -Звичайно, по масивам можна ітеруватися. Але є багато інших вбудованих об’єктів, які також можна ітерувати. Наприклад, рядки також можна ітерувати. +Звичайно, по масивах можна ітеруватися. Але є багато інших вбудованих об’єктів, які також можна ітерувати. Наприклад, рядки також можна ітерувати. -Якщо об’єкт технічно не є масивом, а представляє колекцію (list, set) чогось, то `for..of` - чудовий синтаксис для його обходу, тому давайте подивимося, як змусити його працювати. +Якщо об’єкт технічно не є масивом, а представляє колекцію (list, set) чогось, то `for..of` -- чудовий синтаксис для його обходу, тому подивімось, як змусити його працювати. ## Symbol.iterator -Ми можемо легко зрозуміти концепцію ітеративних об’єктіва, зробивши її власноруч. +Ми можемо легко зрозуміти концепцію ітеративних об’єктів, зробивши її власноруч. Наприклад, у нас є об’єкт, який не є масивом, але виглядає придатним для `for..of`. @@ -75,7 +75,7 @@ for (let num of range) { Отже, об’єкт, що ітерує відокремлений від об’єкта, який він ітерує. -Технічно, ми можемо об’єднати їх і використовувати `range` в якості ітератора, щоб зробити код більш простим. +Технічно, ми можемо об’єднати їх і використовувати `range` в якості ітератора, щоб зробити код простішим. Подібно до цього: @@ -103,15 +103,15 @@ for (let num of range) { } ``` -Тепер `range[Symbol.iterator]()` повертає сам об'єкт `range`: він має необхідний `next()` метод і пам'ятає поточну ітерацію прогресу в `this.current`. Коротше? Так. А іноді це також добре. +Тепер `range[Symbol.iterator]()` повертає сам об’єкт `range`: він має необхідний `next()` метод і пам’ятає поточну ітерацію прогресу в `this.current`. Коротше? Так. А іноді це також добре. -Недоліком є те, що тепер неможливо мати два `for..of` цикли паралельно для проходження через об’єкт: вони будуть ділити ітераційний стан, тому що є тільки один ітератор -- сам об'єкт. Але два параллельних for-of це рідкісний випадок, навіть у асинхронізованих сценаріях. +Недоліком є те, що тепер неможливо мати два `for..of` цикли паралельно для проходження через об’єкт: вони будуть ділити ітераційний стан, тому що є тільки один ітератор -- сам об’єкт. Але два паралельних for-of це рідкісний випадок, навіть у асинхронізованих сценаріях. ```smart header="Infinite iterators" -Також можливі нескінченні ітератори. Наприклад, `range` стає нескінченним для `range.to = Infinity`. Або ми можемо зробити ітерований об'єкт, який генерує нескінченну послідовність псевдорандомних чисел. Це також може бути корисним. +Також можливі нескінченні ітератори. Наприклад, `range` стає нескінченним для `range.to = Infinity`. Або ми можемо зробити ітерований об’єкт, який генерує нескінченну послідовність псевдорандомних чисел. Це також може бути корисним. Немає обмежень на `next`, він може повертати все більше і більше значень, це нормально. -Звичайно, `for..of` цикли через такий об’єкт буде безкінечним. Але ми завжди можемо зупинити його за допомогою `break`. +Звичайно, `for..of` цикли через такий об’єкт буде нескінченним. Але ми завжди можемо зупинити його за допомогою `break`. ``` @@ -139,7 +139,7 @@ for (let char of str) { ## Виклик ітератора явно -Для більш глибокого розуміння, давайте подивимося, як явно використовувати ітератор. +Для глибшого розуміння, подивімось, як явно використовувати ітератор. Ми будемо ітерувати рядок точно так само, як для `for..of`, але з прямими викликами. Цей код створює ітератор рядка і отримує значення від нього "вручну": @@ -166,17 +166,17 @@ while (true) { Ці два офіційних терміни виглядають подібними, але дуже різні. Будь ласка, переконайтеся, що ви добре розумієте їх, щоб уникнути плутанини. -- *Ітеровані* -- це об'єкти, які реалізують метод `Symbol.iterator`, як описано вище. -- *Псевдомасиви* -- це об'єкти, які мають індекси та `length`, тому вони виглядають як масиви. +- *Ітеровані* -- це об’єкти, які реалізують метод `Symbol.iterator`, як описано вище. +- *Псевдомасиви* -- це об’єкти, які мають індекси та `length`, тому вони виглядають як масиви. -Коли ми використовуємо JavaScript для практичних завдань у браузері або будь-якому іншому середовищі, ми можемо зустріти об'єкти, які є ітерованими або масивами, або обома. +Коли ми використовуємо JavaScript для практичних завдань у браузері або будь-якому іншому середовищі, ми можемо зустріти об’єкти, які є ітерованими або масивами, або обома. Наприклад, рядки є ітерованими об’єктами (`for..of` працює на них) та псевдомасивами (у них є числові індекси та `length`). Але ітерований об’єкт може не бути масивом. І навпаки, псевдомасив може бути не ітерованим об’єктом. Наприклад, `range` у прикладі вище є ітерованим об’єктом, але не масивом, тому що він не має індексованих властивостей та `length`. -І ось об'єкт, який є псевдомасивом, але не ітерованим об’єктом: +І ось об’єкт, який є псевдомасивом, але не ітерованим об’єктом: ```js run let arrayLike = { // має індекси та length => псевдомасив @@ -191,7 +191,7 @@ for (let item of arrayLike) {} */!* ``` -Обидва, ітерований об’єкт та псевдомасив, як правило є *не масивами*, вони не мають `push`,` pop` та ін. Це досить незручно, якщо у нас є такий об’єкт і ми хочемо працювати з ним як з масивом. НаприкладМи хотіли б працювати з `angy` за допомогою методів масиву. Як цього досягти? +Обидва, ітерований об’єкт та псевдомасив, як правило є *не масивами*, вони не мають `push`,` pop` та ін. Це досить незручно, якщо у нас є такий об’єкт і ми хочемо працювати з ним як з масивом. Наприклад, ми хотіли б працювати з `angy` за допомогою методів масиву. Як цього досягти? ## Array.from @@ -212,7 +212,7 @@ let arr = Array.from(arrayLike); // (*) alert(arr.pop()); // Світ (метод працює) ``` -`Array.from` у рядку `(*)` бере об'єкт, перевіряє його на ітерабельність або те, що це псевдомасив, потім створює новий масив і копіює до нього всі елементи. +`Array.from` у рядку `(*)` бере об’єкт, перевіряє його на ітерабельність або те, що це псевдомасив, потім створює новий масив і копіює до нього всі елементи. Те ж саме відбувається і з ітерованим об’єктом: @@ -270,7 +270,7 @@ alert(chars); ...Але це коротше. -Ми навіть можемо побудувати на ньому `slice`, що підтримує сутогатні пари: +Ми навіть можемо побудувати на ньому `slice`, що підтримує сурогатні пари: ```js run function slice(str, start, end) { @@ -288,18 +288,18 @@ alert( str.slice(1, 3) ); // сміття (дві частини з різних ## Підсумки -Об'єкти, які можна використовуватися у `for..of`, називаються *ітерованими*. +Об’єкти, які можна використовуватися у `for..of`, називаються *ітерованими*. - Технічно ітеровані об’єкти повинні реалізовувати метод з назвою `Symbol.iterator`. - Результат `obj[Symbol.iterator]()` називається *ітератором*. Він забезпечує подальший процес ітерації. - An iterator must have the method named `next()` that returns an object `{done: Boolean, value: any}`, here `done:true` denotes the end of the iteration process, otherwise the `value` is the next value. - - Ітератор повинен мати метод з назвою `next()`, який повертає об'єкт `{done: Boolean, value: any}`, де `done: true` означає кінець процесу ітерації, інакше `value` є наступним значенням. + - Ітератор повинен мати метод з назвою `next()`, який повертає об’єкт `{done: Boolean, value: any}`, де `done: true` означає кінець процесу ітерації, інакше `value` є наступним значенням. - Метод `Symbol.iterator` автоматично викликається `for..of`, але ми також можемо це зробити безпосередньо. - Вбудовані ітеровані об’єкти, такі як рядки або масиви, також реалізують `Symbol.iterator`. - Рядковий ітератор знає про сурогатні пари. -Об'єкти, які мають індексовані властивості та `length`, називаються *псевдомасивами*. Такі об’єкти також можуть мати інші властивості та методи, але не мають вбудованих методів масивів. +Об’єкти, які мають індексовані властивості та `length`, називаються *псевдомасивами*. Такі об’єкти також можуть мати інші властивості та методи, але не мають вбудованих методів масивів. Якщо ми заглянемо в специфікацію -- ми побачимо, що більшість вбудованих методів припускають, що вони працюють з ітерованими об’єктами або псевдомасивами замість "реальних" масивів, тому що це більш абстрактно. From c3215c36ce6b6ac8d44ee1f03b052eedf8b75e64 Mon Sep 17 00:00:00 2001 From: Mykola Sopiha Date: Sat, 4 Sep 2021 15:55:02 +0300 Subject: [PATCH 5/5] iterables --- 1-js/05-data-types/06-iterable/article.md | 1 + 1 file changed, 1 insertion(+) diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md index a91866186..286eb1d9c 100644 --- a/1-js/05-data-types/06-iterable/article.md +++ b/1-js/05-data-types/06-iterable/article.md @@ -109,6 +109,7 @@ for (let num of range) { ```smart header="Infinite iterators" Також можливі нескінченні ітератори. Наприклад, `range` стає нескінченним для `range.to = Infinity`. Або ми можемо зробити ітерований об’єкт, який генерує нескінченну послідовність псевдорандомних чисел. Це також може бути корисним. + Немає обмежень на `next`, він може повертати все більше і більше значень, це нормально. Звичайно, `for..of` цикли через такий об’єкт буде нескінченним. Але ми завжди можемо зупинити його за допомогою `break`. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy