-
Notifications
You must be signed in to change notification settings - Fork 630
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Добавляет доку для метода массива with()
#5013
Merged
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
6e9d117
Добавляет draft доки про метод Array.with()
vitya-ne 63c0ead
Корректировка 1
vitya-ne e1cd791
Добавляет примеры и пояснения
vitya-ne 8dc893d
Корректирует формулировки и примеры
vitya-ne 3ce0e25
Добавляет подсказку о поддержке метода, bсправляет неточности
vitya-ne fe2be54
Исправляет ссылку
vitya-ne 42d11a7
Исправлет орфографию: 'ё' -> 'e'
vitya-ne 09c7f45
Немного редачит
TatianaFokina 0c9ddc9
Уважает ё
TatianaFokina 2be813b
Добавляет информацию в раздел people
vitya-ne b46e43a
Merge remote-tracking branch 'origin/doka/array-with' into doka/array…
vitya-ne 861d100
Упрощает формулировку и добавляет пример
vitya-ne bc9e592
Корректирует формулировки и примеры
vitya-ne 40b9eae
Update js/array-with/index.md
vitya-ne a8461ce
Update js/array-with/index.md
vitya-ne b2bf601
Update js/array-with/index.md
vitya-ne 8012e92
Корректирует после ревью Полины
vitya-ne 708a001
Дополняет примером вызова без аргументов
vitya-ne 043caaa
Дополняет пояснение проблем использования грязной функции
vitya-ne 3080399
Исправляет ошибки
vitya-ne d3b8046
Поправляет метод консоли для ошибки
vitya-ne 4156f24
Добавляет ачивку
TatianaFokina File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
--- | ||
title: "`.with()`" | ||
description: "Создаёт новый массив, изменяя один элемент исходного." | ||
authors: | ||
- vitya-ne | ||
related: | ||
- js/arrays | ||
- js/ref-type-vs-value-type | ||
- js/array-find | ||
tags: | ||
- doka | ||
--- | ||
|
||
## Кратко | ||
|
||
Метод `with()` изменяет значение одного из элементов массива и возвращает новый массив, без изменения исходного массива. | ||
|
||
## Пример | ||
|
||
Изменим элемент 'white' на 'blue': | ||
|
||
```js | ||
const colors = ['red', 'green', 'white'] | ||
|
||
const newColors = colors.with(2, 'blue') | ||
|
||
console.log(newColors) | ||
// ['red', 'green', 'blue'] | ||
|
||
console.log(colors) | ||
// Исходный массив остался прежним | ||
// ['red', 'green', 'white'] | ||
``` | ||
|
||
Изменим элемент 'white' на 'blue', используя отрицательный индекс: | ||
|
||
```js | ||
const colors = ['red', 'green', 'white'] | ||
|
||
const newColors = colors.with(-1, 'blue') | ||
|
||
console.log(newColors) | ||
// ['red', 'green', 'blue'] | ||
|
||
console.log(colors) | ||
// Исходный массив остался прежним | ||
// ['red', 'green', 'white'] | ||
``` | ||
|
||
## Как пишется | ||
|
||
`Array.with()` принимает два аргумента: | ||
|
||
- индекс элемента, который нужно изменить; | ||
- новое значение изменяемого элемента. | ||
|
||
Индекс элемента может быть: | ||
|
||
- положительный — для доступа к элементам от начала массива; | ||
- отрицательный — для доступа к элементам с конца массива. Например, `-1` — индекс последнего элемента, `-2` — предпоследнего и т. д. | ||
|
||
`Array.with()` возвращает массив с изменённым элементом. | ||
|
||
Вызов `with()` без аргументов, не приведёт к ошибке. Это равнозначно вызову `with(0, undefined)`: | ||
|
||
```js | ||
const routes = ['/home', '/settings', '/about'] | ||
const newRoutes = routes.with() | ||
|
||
console.log(newRoutes) | ||
// [undefined, '/settings', '/about'] | ||
``` | ||
|
||
Попытка вызвать `with()` со значением индекса за пределами допустимых значений (`index >= array.length || index < -array.length`) приведёт к возникновению ошибки `RangeError`. | ||
|
||
```js | ||
const authors = ['Ф. Кафка', 'Д. Сэлинджер'] | ||
|
||
try { | ||
console.log(authors.with(2, 'К. Воннегут')) | ||
} catch (err) { | ||
console.error('Поймали ошибку! Вот она: ', err.message) | ||
} | ||
// Поймали ошибку! Вот она: Invalid index : 2 | ||
``` | ||
|
||
## Как понять | ||
|
||
При работе с массивами иногда требуется получить новый массив, содержащий изменённую копию исходного массива. Например, напишем функцию для изменения значения первого элемента массива, используя метод `with()`: | ||
|
||
```js | ||
const updateFirstItem = (array, value) => { | ||
return array.with(0, value) | ||
} | ||
``` | ||
|
||
Проверим, как она работает, и убедимся, что исходный массив остался прежним. | ||
|
||
```js | ||
const bears = ['гризли', 'полярный', 'бурый'] | ||
const result = updateFirstItem(bears, 'панда') | ||
|
||
console.log(result) | ||
// ['панда', 'полярный', 'бурый'] | ||
|
||
console.log(bears) | ||
// ['гризли', 'полярный', 'бурый'] | ||
``` | ||
|
||
А вот для сравнения функция, меняющая значение первого элемента в исходном массиве: | ||
|
||
```js | ||
const updateFirstItemDanger = (array, value) => { | ||
const result = array | ||
result[0] = value | ||
return result | ||
} | ||
``` | ||
|
||
Вызов этой функции вернёт тот же результат, но приведёт к изменению исходного массива. Функция `updateFirstItemDanger()`, не может считаться [чистой](/tools/fp/#chistye-funkcii-i-pobochnye-effekty) (pure), так как приводит к изменению данных, не принадлежащих ей (определённых вне её контекста). В [функциональном программировании](/tools/fp/) такое изменение называется побочный эффект. Функции, вызывающие побочные эффекты, имеют ряд недостатков: меньшая предсказуемость, трудность при тестировании. В большинстве случаев такого кода следует избегать. | ||
|
||
```js | ||
const bears = ['гризли', 'полярный', 'бурый'] | ||
const result = updateFirstItemDanger(bears, 'панда') | ||
|
||
console.log(result) | ||
// ['панда', 'полярный', 'бурый'] | ||
|
||
console.log(bears) | ||
// Ой, куда пропал мишка гризли! | ||
// ['панда', 'полярный', 'бурый'] | ||
``` | ||
|
||
Обратите внимание: причина изменения исходного массива при использовании функции `updateFirstItemDanger()` в том, что функция не копирует полученный в качестве аргумента исходный массив в новый, а создаёт ещё одну ссылку на исходный массив. Подробнее об этом можно почитать в разделе [Хранение по ссылке и по значению](/js/ref-type-vs-value-type/#mutacii-i-neizmenyaemost). | ||
|
||
## Подсказки | ||
|
||
💡 `with()` — это удобный способ избежать изменения (мутации) исходного массива. | ||
|
||
💡 `with()` - упрощает изменение элемента, если элементы нужно отсчитывать от конца массива, а не от его начала. Например, это удобно для изменения последнего элемента. Обычно для изменения последнего элемента массива нужно определить его индекс от начала массива. Для это потребуется: | ||
|
||
- узнать длину массива; | ||
- вычислить индекс последнего элемента, используя формулу `lastIndex = arrayLength - 1`. | ||
|
||
Меняем последний элемент используя традиционный подход: | ||
|
||
```js | ||
const words = ['первый', 'второй', 'третий'] | ||
|
||
const lastIndex = words.length - 1 | ||
const newWords = [...words] // создаем копию массива | ||
|
||
newWords[lastIndex] = 'последний' | ||
|
||
console.log(newWords); | ||
// ['первый', 'второй', 'последний'] | ||
``` | ||
|
||
А вот как это можно сделать с использованием `with()`: | ||
|
||
```js | ||
const words = ['первый', 'второй', 'третий'] | ||
|
||
console.log(words.with(-1, 'последний')) | ||
// ['первый', 'второй', 'последний'] | ||
``` | ||
|
||
💡 `with()` может быть использован при объединении функций обработки массива в цепочку вызовов. Каждый метод в цепочке получает результат работы предыдущего. Например: | ||
|
||
```js | ||
const days = ['', 'пн', 'вт', 'ср', 4] | ||
|
||
console.log( | ||
days | ||
.filter(item => typeof item === 'string') | ||
.with(0, 'вс') | ||
.map(item => item.toUpperCase()) | ||
) | ||
// [ 'ВС', 'ПН', 'ВТ', 'СР' ] | ||
``` | ||
|
||
💡 При создании нового массива `with()` выполнит преобразование всех незаполненных ячеек к `undefined`: | ||
|
||
```js | ||
const numbers = [0, , 11, 20, , 30] | ||
|
||
console.log(numbers.with(2, 10)) | ||
// [ 0, undefined, 10, 20, undefined, 30 ] | ||
``` | ||
|
||
💡 Поддержка метода `with()` в основных браузерах и в Node.js появилась сравнительно недавно. Например, попытка использовать `with()` в Node.js v.18.19.0 приведёт к ошибке: | ||
|
||
```js | ||
const array = ['ночь','улица','фонарь'] | ||
try { | ||
console.log(array.with(-1,'январь')) | ||
} catch (err) { | ||
console.error('Поймали ошибку! Вот она: ', err.message) | ||
} | ||
// Поймали ошибку! Вот она: array.with is not a function | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
name: 'Viktar Nezhbart' | ||
url: https://github.com/vitya-ne | ||
badges: | ||
- first-contribution-small | ||
- workafrolic | ||
--- |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Кажется в примере ниже не создается новый массив, а расширяется копия исходного
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Я не очень понял твой комент.
with()
создаёт новый массив.Ты имела ввиду, что в примере нужно добавить строку с присвоением ?
вот так:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
В твоем примере все хорошо, это я просто не туда посмотрела. Извини пжлст :)