This page was translated from English by the community.Learn more and join the MDN Web Docs community.
Массивы
В финальной статье этого раздела, мы познакомимся с массивами — лаконичным способом хранения списка элементов под одним именем. Мы поймём, чем они полезны, затем узнаем, как создать массив, получить, добавить и удалить элементы, хранящиеся в массиве.
| Необходимые навыки: | Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание о том, что такое JavaScript. |
|---|---|
| Цель: | Понять, что такое массивы и как использовать их в JavaScript. |
In this article
Что такое массив?
Массивы обычно описываются как «объекты, подобные спискам»; они представляют собой в основном отдельные объекты, которые содержат несколько значений, хранящихся в списке. Объекты массива могут храниться в переменных и обрабатываться во многом так же, как и любой другой тип значения, причём разница заключается в том, что мы можем получить доступ к каждому значению внутри списка отдельно и делать супер полезные и эффективные вещи со списком, а также делать то же самое для каждого из значений. Представим, что у нас есть список продуктов и их цены, хранящиеся в массиве, и мы хотим их просмотреть и распечатать на счёте-фактуре, общая сумма всех цен и распечатка общей цены внизу.
Если бы у нас не было массивов, мы должны были бы хранить каждый элемент в отдельной переменной, а затем вызывать код, выполняющий печать и добавляющий отдельно каждый элемент. Написание такого кода займёт намного больше времени, сам код будет менее эффективным и подверженным ошибкам. Если бы у нас было 10 элементов для добавления в счёт-фактуру, это ещё куда ни шло, но как насчёт 100 предметов? Или 1000? Мы вернёмся к этому примеру позже в статье.
Как и в предыдущих статьях, давайте узнаем о реальных основах работы с массивами, введя некоторые примеры вконсоль разработчика.
Создание массива
Массивы создаются из квадратных скобок , которые содержат список элементов, разделённых запятыми.
Допустим, мы бы хотели хранить список покупок в массиве — мы бы сделали что-то вроде этого. Введите следующие строчки в вашу консоль:
jsvar shopping = ["bread", "milk", "cheese", "hummus", "noodles"];shopping;В данном случае, каждый элемент в массиве — это строка , но имейте в виду, что вы можете хранить любой элемент в массиве — строку, число, объект, другую переменную, даже другой массив. Вы также можете перемешивать типы элементов — они не должны все быть числами, строками, и так далее. Попробуйте это:
jsvar sequence = [1, 1, 2, 3, 5, 8, 13];var random = ["tree", 795, [0, 1, 2]];Попробуйте сами создать несколько массивов, перед тем как двигаться дальше.
Получение и изменение элементов массива
Вы можете после этого получать доступ к отдельным элементам в массиве, используя квадратные скобки, таким же способом каким выполучаете доступ к буквам в строке.
Введите следующее в вашу консоль:
jsshopping[0];// возвращает "bread"Вы также можете изменять элемент в массиве, просто дав отдельному элементу массива новое значение. Попробуйте это:
jsshopping[0] = "tahini";shopping;// shopping теперь возвратит [ "tahini", "milk", "cheese", "hummus", "noodles" ]Примечание:Мы уже упоминали это прежде, но просто как напоминание — компьютеры начинают считать с нуля!
Заметьте, что массив внутри массива называется многомерным массивом. Вы можете получить доступ к элементу внутри массива, который сам находится внутри другого массива, объединив два набора квадратных скобок. Например, для доступа к одному из элементов внутри массива, который является третьим элементом внутри массива
random(см. предыдущую секцию данной статьи), мы могли бы сделать что-то вроде этого:jsrandom[2][2];Попробуйте внести некоторые дополнительные изменения в свои примеры массивов, прежде чем двигаться дальше.
Нахождение длины массива
Вы можете найти длину массива (количество элементов в нём) точно таким же способом, как вы находите длину строки (в символах) — используя свойствоlength. Попробуйте следующее:
sequence.length;// должно возвратить 7Это свойство имеет и другие применения, но чаще всего используется, чтобы сказать, что цикл продолжается, пока он не зациклится на всех элементах массива. Так, например:
var sequence = [1, 1, 2, 3, 5, 8, 13];for (var i = 0; i < sequence.length; i++) { console.log(sequence[i]);}В будущих статьях вы узнаете о циклах, но вкратце этот код говорит:
- Начать цикл с номера позиции 0 в массиве.
- Остановить цикл на номере элемента, равном длине массива. Это будет работать для массива любой длины, но в этом случае он остановит цикл на элементе номер 7 (это хорошо, поскольку последний элемент, который мы хотим, чтобы цикл был закрыт, равен 6).
- Для каждого элемента вернуть его значение в консоли браузера с помощью
console.log().
Некоторые полезные методы массивов
В этом разделе мы рассмотрим некоторые полезные методы, связанные с массивом, которые позволяют нам разбивать строки на элементы массива и наоборот, а также добавлять новые элементы в массивы.
Преобразование между строками и массивами
Часто у вас могут быть некоторые необработанные данные, содержащиеся в большой длинной строке, и вы можете захотеть разделить полезные пункты до более удобной и полезной формы, а затем сделать что-то для них, например отобразить их в таблице данных. Для этого мы можем использовать методsplit (). В его простейшей форме он принимает единственный параметр, символ, который вы хотите отделить в строке, и возвращает подстроки между разделителем как элементы в массиве.
Примечание:Хорошо, технически это строковый метод, не метод массива, но мы поместили его в массивы, так как он хорошо подходит для них.
Поиграем с этим, посмотрим как это работает. Сначала, создадим строку в вашей консоли:
jsvar myData = "Manchester,London,Liverpool,Birmingham,Leeds,Carlisle";Теперь разделим ee посредством запятой:
jsvar myArray = myData.split(",");myArray;Наконец, попробуйте найти длину вашего нового массива и извлечь из него некоторые элементы:
jsmyArray.length;myArray[0]; // первый элемент в массивеmyArray[1]; // второй элемент в массивеmyArray[myArray.length - 1]; // последний элемент в массивеВы можете сделать обратное используя метод
join(). Попробуйте следующее:jsvar myNewString = myArray.join(",");myNewString;Другой способ преобразования массива в строку - использовать метод
toString().toString(), возможно, проще,чемjoin()поскольку он не принимает параметр, но это ограничивает его. Сjoin()вы можете указать разные разделители (попробуйте выполнить шаг 4 с другим символом, кроме запятой).jsvar dogNames = ["Rocket", "Flash", "Bella", "Slugger"];dogNames.toString(); //Rocket,Flash,Bella,Slugger
Добавление и удаление элементов массива
Мы ещё не рассмотрели добавление и удаление элементов массива - давайте посмотрим на это сейчас. Мы будем использовать массивmyArray , с которым мы столкнулись в предыдущем разделе. Если вы ещё не прошли этот раздел, сначала создайте массив в консоли:
var myArray = [ "Manchester", "London", "Liverpool", "Birmingham", "Leeds", "Carlisle",];Прежде всего, чтобы добавить или удалить элемент с конца массива, мы можем использоватьpush() иpop() соответственно.
Давайте сначала используем метод
push()— заметьте, что вам нужно указать один или более элементов, которые вы хотите добавить в конец своего массива. Попробуйте это:jsmyArray.push("Cardiff");myArray;myArray.push("Bradford", "Brighton");myArray;При завершении вызова метода возвращается новая длина массива. Если бы вы хотели сохранить новую длину массива в переменной, вы бы могли сделать что-то вроде этого:
jsvar newLength = myArray.push("Bristol");myArray;newLength;Удаление последнего элемента массива можно совершить с помощью вызова метода
pop(). Попробуйте это:jsmyArray.pop();Когда вызов метода завершается, возвращается удалённый элемент. Вы бы могли также сделать такое:
jsvar removedItem = myArray.pop();myArray;removedItem;
unshift() иshift() работают точно таким же способом, за исключением того что они работают в начале массива, а не в конце.
Сначала, попробуем метод
unshift():jsmyArray.unshift("Edinburgh");myArray;Теперь
shift(); попробуйте эти!jsvar removedItem = myArray.shift();myArray;removedItem;
Практика: Печать продуктов!
Вернёмся к описанному выше примеру - распечатываем названия продуктов и цен на счёт-фактуру, затем суммируем цены и печатаем их внизу. В приведённом ниже редактируемом примере есть комментарии, содержащие числа - каждая из этих отметок является местом, где вы должны добавить что-то в код. Они заключаются в следующем:
- Ниже комментария
// number 1имеется ряд строк, каждая из которых содержит название продукта и цену, разделённые двоеточием. Нужно превратить их в массив и сохранить его под названиемproducts. - На строке с комментарием
// number 2начинается цикл for. В строке цикла имеетсяi <= 0, что является условием , которое заставляет цикл for выполняться только один раз, так как это значение i сообщает циклу: «останавливаться, когдаiменьше или равен 0», при этомiначинается с 0. Нужно заменитьi <= 0условным тестом, который останавливает цикл, когдаiперестаёт быть меньше длины массиваproducts. - Под комментарием
// number 3мы хотим, чтобы вы написали строку кода, которая разбивает текущий элемент массива (name:price) на два отдельных элемента: один содержит только имя, а другой - содержащее только цену. Если не знаете, как это сделать, ещё раз просмотрите статьюПолезные строковые методы, а лучше, посмотрите разделПреобразование между строками и массивами этой статьи. - В рамках приведённой выше строки нужно преобразовать цену из строки в число. Если не помните, как это сделать, ознакомьтесь со статьёйстроки в JavaScript.
- В верхней части кода есть переменная с именем
total, которая содержит значение0. Внутри цикла (под комментарием// number 4) нужно добавить строку, которая добавляет текущую цену товара к этой сумме на каждой итерации цикла, так чтобы в конце кода была выведена корректная сумма в счёт-фактуре. Для этого вам может понадобитсяоператор присваивания. - Под комментарием
// number 5нужно изменить строку так, чтобы переменнаяitemTextбыла равна "current item name — $current item price", например "Shoes — $23.99" для каждого случая, чтобы корректная информация для каждого элемента была напечатана в счёте-фактуре. Здесь обычная конкатенация строк, которая должна быть вам знакома.
<!-- Не выделяйте тут ничего, не копируйте, не всавляйте! Еле починил --><h2>Live output</h2><div> <ul></ul> <p></p></div><h2>Editable code</h2><p> Press Esc to move focus away from the code area (Tab inserts a tab character).</p><textarea>var list = document.querySelector('.output ul');var totalBox = document.querySelector('.output p');var total = 0;list.innerHTML = '';totalBox.textContent = '';// number 1 'Underpants:6.99' 'Socks:5.99' 'T-shirt:14.99' 'Trousers:31.99' 'Shoes:23.99';for (var i = 0; i <= 0; i++) { // number 2 // number 3 // number 4 // number 5 itemText = 0; var listItem = document.createElement('li'); listItem.textContent = itemText; list.appendChild(listItem);}totalBox.textContent = 'Total: $' + total.toFixed(2);</textarea><div> <input type="button" value="Reset" /> <input type="button" value="Show solution" /></div>var textarea = document.getElementById("code");var reset = document.getElementById("reset");var solution = document.getElementById("solution");var code = textarea.value;var userEntry = textarea.value;function updateCode() { eval(textarea.value);}reset.addEventListener("click", function () { textarea.value = code; userEntry = textarea.value; solutionEntry = jsSolution; solution.value = "Show solution"; updateCode();});solution.addEventListener("click", function () { if (solution.value === "Show solution") { textarea.value = solutionEntry; solution.value = "Hide solution"; } else { textarea.value = userEntry; solution.value = "Show solution"; } updateCode();});var jsSolution = "var list = document.querySelector('.output ul');\nvar totalBox = document.querySelector('.output p');\nvar total = 0;\nlist.innerHTML = '';\ntotalBox.textContent = '';\n\nvar products = ['Underpants:6.99',\n 'Socks:5.99',\n 'T-shirt:14.99',\n 'Trousers:31.99',\n 'Shoes:23.99'];\n\nfor(var i = 0; i < products.length; i++) {\n var subArray = products[i].split(':');\n var name = subArray[0];\n var price = Number(subArray[1]);\n total += price;\n itemText = name + ' — $' + price;\n\n var listItem = document.createElement('li');\n listItem.textContent = itemText;\n list.appendChild(listItem);\n}\n\ntotalBox.textContent = 'Total: $' + total.toFixed(2);";var solutionEntry = jsSolution;textarea.addEventListener("input", updateCode);window.addEventListener("load", updateCode);// stop tab key tabbing out of textarea and// make it write a tab at the caret position insteadtextarea.onkeydown = function (e) { if (e.keyCode === 9) { e.preventDefault(); insertAtCaret("\t"); } if (e.keyCode === 27) { textarea.blur(); }};function insertAtCaret(text) { var scrollPos = textarea.scrollTop; var caretPos = textarea.selectionStart; var front = textarea.value.substring(0, caretPos); var back = textarea.value.substring( textarea.selectionEnd, textarea.value.length, ); textarea.value = front + text + back; caretPos = caretPos + text.length; textarea.selectionStart = caretPos; textarea.selectionEnd = caretPos; textarea.focus(); textarea.scrollTop = scrollPos;}// Update the saved userCode every time the user updates the text area codetextarea.onkeyup = function () { // We only want to save the state when the user code is being shown, // not the solution, so that solution is not saved over the user code if (solution.value === "Show solution") { userEntry = textarea.value; } else { solutionEntry = textarea.value; } updateCode();};html { font-family: sans-serif;}h2 { font-size: 16px;}.a11y-label { margin: 0; text-align: right; font-size: 0.7rem; width: 98%;}body { margin: 10px; background-color: #f5f9fa;}Практика: Топ 5 поисковых запросов
Хорошим тоном, является использование методов массива, таких какpush () иpop () - это когда вы ведёте запись активных элементов в веб-приложении. Например, в анимированной сцене может быть массив объектов, представляющих текущую отображаемую фоновую графику и вам может потребоваться только 50 одновременных отображений по причинам производительности или беспорядка. Когда новые объекты создаются и добавляются в массив, более старые могут быть удалены из массива для поддержания нужного числа.
В этом примере мы собираемся показать гораздо более простое использование - ниже мы даём вам поддельный поисковый сайт с полем поиска. Идея заключается в том, что когда в поле поиска вводятся запросы, в списке отображаются 5 предыдущих поисковых запросов. Когда число терминов превышает 5, последний член начинает удаляться каждый раз, когда новый член добавляется в начало, поэтому всегда отображаются 5 предыдущих терминов.
Примечание:В реальном приложении для поиска вы, вероятно, сможете щёлкнуть предыдущие условия поиска, чтобы вернуться к предыдущим поисковым запросам и отобразите фактические результаты поиска! На данный момент мы просто сохраняем его.
Чтобы завершить приложение, вам необходимо:
- Добавьте строку под комментарием
// number 1, которая добавляет текущее значение, введённое в ввод поиска, к началу массива. Его можно получить с помощьюsearchInput.value. - Добавьте строку под комментарием
// number 2, которая удаляет значение, находящееся в конце массива.
<!-- Здесь тоже ничего не выделяйте, не копируйте, не всавляйте! Еле починил --><h2>Live output</h2><div> <input type="text" /><button>Search</button> <ul></ul></div><h2>Editable code</h2><p> Press Esc to move focus away from the code area (Tab inserts a tab character).</p><textarea>var list = document.querySelector('.output ul');var searchInput = document.querySelector('.output input');var searchBtn = document.querySelector('.output button');list.innerHTML = '';var myHistory = [];searchBtn.onclick = function() { // we will only allow a term to be entered if the search input isn't empty if (searchInput.value !== '') { // number 1 // empty the list so that we don't display duplicate entries // the display is regenerated every time a search term is entered. list.innerHTML = ''; // loop through the array, and display all the search terms in the list for (var i = 0; i < myHistory.length; i++) { itemText = myHistory[i]; var listItem = document.createElement('li'); listItem.textContent = itemText; list.appendChild(listItem); } // If the array length is 5 or more, remove the oldest search term if (myHistory.length >= 5) { // number 2 } // empty the search input and focus it, ready for the next term to be entered searchInput.value = ''; searchInput.focus(); }}</textarea><div> <input type="button" value="Reset" /> <input type="button" value="Show solution" /></div>html { font-family: sans-serif;}h2 { font-size: 16px;}.a11y-label { margin: 0; text-align: right; font-size: 0.7rem; width: 98%;}body { margin: 10px; background: #f5f9fa;}var textarea = document.getElementById("code");var reset = document.getElementById("reset");var solution = document.getElementById("solution");var code = textarea.value;var userEntry = textarea.value;function updateCode() { eval(textarea.value);}reset.addEventListener("click", function () { textarea.value = code; userEntry = textarea.value; solutionEntry = jsSolution; solution.value = "Show solution"; updateCode();});solution.addEventListener("click", function () { if (solution.value === "Show solution") { textarea.value = solutionEntry; solution.value = "Hide solution"; } else { textarea.value = userEntry; solution.value = "Show solution"; } updateCode();});var jsSolution = "var list = document.querySelector('.output ul');\nvar searchInput = document.querySelector('.output input');\nvar searchBtn = document.querySelector('.output button');\n\nlist.innerHTML = '';\n\nvar myHistory= [];\n\nsearchBtn.onclick = function() {\n if(searchInput.value !== '') {\n myHistory.unshift(searchInput.value);\n\n list.innerHTML = '';\n\n for(var i = 0; i < myHistory.length; i++) {\n itemText = myHistory[i];\n var listItem = document.createElement('li');\n listItem.textContent = itemText;\n list.appendChild(listItem);\n }\n\n if(myHistory.length >= 5) {\n myHistory.pop();\n }\n\n searchInput.value = '';\n searchInput.focus();\n }\n}";var solutionEntry = jsSolution;textarea.addEventListener("input", updateCode);window.addEventListener("load", updateCode);// stop tab key tabbing out of textarea and// make it write a tab at the caret position insteadtextarea.onkeydown = function (e) { if (e.keyCode === 9) { e.preventDefault(); insertAtCaret("\t"); } if (e.keyCode === 27) { textarea.blur(); }};function insertAtCaret(text) { var scrollPos = textarea.scrollTop; var caretPos = textarea.selectionStart; var front = textarea.value.substring(0, caretPos); var back = textarea.value.substring( textarea.selectionEnd, textarea.value.length, ); textarea.value = front + text + back; caretPos = caretPos + text.length; textarea.selectionStart = caretPos; textarea.selectionEnd = caretPos; textarea.focus(); textarea.scrollTop = scrollPos;}// Update the saved userCode every time the user updates the text area codetextarea.onkeyup = function () { // We only want to save the state when the user code is being shown, // not the solution, so that solution is not saved over the user code if (solution.value === "Show solution") { userEntry = textarea.value; } else { solutionEntry = textarea.value; } updateCode();};Заключение
Прочитав эту статью, мы уверены, что вы согласитесь, что массивы кажутся довольно полезными; вы увидите, что они появляются повсюду в JavaScript, часто в сочетании с циклами, чтобы делать то же самое для каждого элемента массива. Мы научим вас всем полезным основам, которые нужно знать о циклах в следующем модуле, но пока вы должны себе похлопать и воспользоваться заслуженным перерывом; вы проработали все статьи в этом модуле!
Осталось только выполнить тестовую задачу, которая проверит ваше понимание статей, которые вы прочли до этого момента. Удачи!
Посмотрите также
- Indexed collections — an advanced level guide to arrays and their cousins, typed arrays.
Array— theArrayobject reference page — for a detailed reference guide to the features discussed in this page, and many more.