Лекция
Привет, сегодня поговорим про массивы c числовыми индексами, обещаю рассказать все что знаю. Для того чтобы лучше понимать что такое массивы c числовыми индексами , настоятельно рекомендую прочитать все из категории Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend).
pop/push
, shift/unshift
length
length
для укорачивания массиваnew Array
new Array()
Массив с числовыми индексами - это коллекция данных, которая хранит сколько угодно значений, причем у каждого значения - свой уникальный номер.
Если переменная — это коробка для данных, то массив — это шкаф с нумерованными ячейками, в каждой из которых могут быть свои данные.
Например, при создании электронного магазина нужно хранить список товаров — для таких задач и придуман массив.
Синтаксис для создания нового массива — квадратные скобки со списком элементов внутри.
Пустой массив:
var arr = []; |
Массив fruits
с тремя элементами:
var fruits = [ "Яблоко" , "Апельсин" , "Слива" ]; |
Элементы нумеруются, начиная с нуля. Чтобы получить нужный элемент из массива — указывается его номер в квадратных скобках:
1 |
var fruits = [ "Яблоко" , "Апельсин" , "Слива" ]; |
2 |
3 |
alert(fruits[0]); // Яблоко |
4 |
alert(fruits[1]); // Апельсин |
5 |
alert(fruits[2]); // Слива |
Элемент можно всегда заменить:
fruits[2] = 'Груша' ; // теперь ["Яблоко", "Апельсин", "Груша"] |
fruits[3] = 'Лимон' ; // теперь ["Яблоко", "Апельсин", "Груша", "Лимон"] |
Общее число элементов, хранимых в массиве, содержится в его свойстве length
:
1 |
var fruits = [ "Яблоко" , "Апельсин" , "Груша" ]; |
2 |
3 |
alert(fruits.length); // 3 |
Через alert
можно вывести и массив целиком. При этом его элементы будут перечислены через запятую:
1 |
var fruits = [ "Яблоко" , "Апельсин" , "Груша" ]; |
2 |
3 |
alert(fruits); // Яблоко,Апельсин,Груша |
В массиве может храниться любое число элементов любого типа. В том числе, строки, числа, объекты и т.п.:
1 |
// микс значений |
2 |
var arr = [ 1, 'Имя' , { name: 'Петя' }, true ]; |
3 |
4 |
// получить объект из массива и тут же -- его свойство |
5 |
alert( arr[2].name ); // Петя |
pop/push
, shift/unshift
Одно из применений массива — это очередь. В классическом программировании так называют упорядоченную коллекцию элементов, такую что элементы добавляются в конец, а обрабатываются — с начала.
В реальной жизни эта структура данных встречается очень часто. Например, очередь сообщений, которые надо отослать.
Очень близка к очереди еще одна структура данных: стек. Это такая коллекция элементов, в которой новые элементы добавляются в конец и берутся с конца.
Например, стеком является колода карт, в которую новые карты кладутся сверху, и берутся — тоже сверху.
Для того, чтобы реализовывать эти структуры данных, и просто для более удобной работы с началом и концом массива существуют специальные методы.
pop
1 |
var fruits = [ "Яблоко" , "Апельсин" , "Груша" ]; |
2 |
3 |
alert( fruits.pop() ); // удалили "Груша" |
4 |
5 |
alert(fruits); // Яблоко, Апельсин |
push
1 |
var fruits = [ "Яблоко" , "Апельсин" ]; |
2 |
3 |
fruits.push( "Груша" ); |
4 |
5 |
alert(fruits); // Яблоко, Апельсин, Груша |
Является полным аналогом fruits[fruits.length] = ...
.
shift
1 |
var fruits = [ "Яблоко" , "Апельсин" , "Груша" ]; |
2 |
3 |
alert( fruits.shift() ); // удалили Яблоко |
4 |
5 |
alert(fruits); // Апельсин, Груша |
unshift
1 |
var fruits = [ "Апельсин" , "Груша" ]; |
2 |
3 |
fruits.unshift( 'Яблоко' ); |
4 |
5 |
alert(fruits); // Яблоко, Апельсин, Груша |
Методы push
и unshift
могут добавлять сразу по несколько элементов:
1 |
var fruits = [ "Яблоко" ]; |
2 |
3 |
fruits.push( "Апельсин" , "Персик" ); |
4 |
fruits.unshift( "Ананас" , "Лимон" ); |
5 |
6 |
// результат: ["Ананас", "Лимон", "Яблоко", "Апельсин", "Персик"] |
7 |
alert(fruits); |
Массив — это объект, где в качестве ключей выбраны цифры, с дополнительными методами и свойством length
.
Так как это объект, то в функцию он передается по ссылке:
01 |
function eat(arr) { |
02 |
arr.pop(); |
03 |
} |
04 |
05 |
var arr = [ "нам" , "не" , "страшен" , "серый" , "волк" ] |
06 |
07 |
alert(arr.length); // 5 |
08 |
eat(arr); |
09 |
eat(arr); |
10 |
alert(arr.length); // 3, в функцию массив не скопирован, а передана ссылка |
Еще одно следствие — можно присваивать в массив любые свойства.
Например:
1 |
var fruits = []; // создать массив |
2 |
3 |
fruits[99999] = 5; // присвоить свойство с любым номером |
4 |
5 |
fruits.age = 25; // назначить свойство со строковым именем |
.. Об этом говорит сайт https://intellect.icu . Но массивы для того и придуманы в JavaScript, чтобы удобно работать именно с упорядоченными, нумерованными данными. Для этого в них существуют специальные методы и свойство length
.
Как правило, нет причин использовать массив как обычный объект, хотя технически это и возможно.
Если в массиве есть пропущенные индексы, то при выводе в большинстве браузеров появляются «лишние» запятые, например:
1 |
var a = []; |
2 |
a[0] = 0; |
3 |
a[5] = 5; |
4 |
5 |
alert(a); // 0,,,,,5 |
Эти запятые появляются потому, что алгоритм вывода массива идет от 0
доarr.length
и выводит все через запятую. Отсутствие значений дает несколько запятых подряд.
Методы push/pop
выполняются быстро, а shift/unshift
— медленно.
Чтобы понять, почему работать с концом массива — быстрее, чем с его началом, разберем происходящее подробнее.
Операция shift
выполняет два действия:
length
.При этом, так как все элементы находятся в своих ячейках, просто очистить ячейку с номером 0
недостаточно. Нужно еще и переместить все ячейки на 1
вниз (красным на рисунке подсвечены изменения):
fruits.shift(); // убрать 1 элемент с начала |
Чем больше элементов в массиве, тем дольше их перемещать.
Аналогично работает unshift
: чтобы добавить элемент в начало массива, нужно сначала перенести все существующие.
У методов push/pop
таких проблем нет. Для того, чтобы удалить элемент, метод pop
очищает ячейку и укорачивает length
.
fruits.pop(); // убрать 1 элемент с конца |
Аналогично работает push
.
Для перебора элементов обычно используется цикл:
1 |
var arr = [ "Яблоко" , "Апельсин" , "Груша" ]; |
2 |
3 |
for ( var i=0; i<arr.length; i++) { |
4 |
alert( arr[i] ); |
5 |
} |
for..in
для массивовТак как массив является объектом, то возможен и вариант for..in
:
1 |
var arr = [ "Яблоко" , "Апельсин" , "Груша" ]; |
2 |
3 |
for ( var key in arr) { |
4 |
alert( arr[key] ); // Яблоко, Апельсин, Груша |
5 |
} |
Недостатки этого способа:
for..in
выведет все свойства объекта, а не только цифровые.
В браузере, при работе с объектами страницы, встречаются коллекции элементов, которые по виду как массивы, но имеют дополнительные нецифровые свойства, которые будут видны в цикле for..in
.
Бывают и библиотеки, которые предоставляют такие коллекции. Например jQuery. С виду — массив, но есть дополнительные свойства. Для перебора только цифровых свойств нужен цикл for(var i=0; i<arr.length...)
for (var i=0; i<arr.length; i++)
в современных браузерах выполняется в 10-100 раз быстрее. Казалось бы, по виду он сложнее, но браузер особым образом оптимизирует такие циклы.Если кратко: цикл for(var i=0; i<arr.length...)
надежнее и быстрее.
length
Встроенные методы для работы с массивом автоматически обновляют его длину length
.
Длина length
— не количество элементов массива, а последний индекс + 1
. Так уж оно устроено.
Это легко увидеть на следующем примере:
1 |
var arr = []; |
2 |
arr[1000] = true ; |
3 |
4 |
alert(arr.length); // 1001 |
Вообще, если у вас элементы массива нумеруются случайно или с большими пропусками, то стоит подумать о том, чтобы использовать обычный объект.
Массивы предназначены именно для работы с непрерывной упорядоченной коллекцией элементов.
length
для укорачивания массиваОбычно нам не нужно самостоятельно менять length
… Но есть один фокус, который можно провернуть.
При уменьшении length
массив укорачивается. Причем этот процесс необратимый, т.е. даже если потом вернуть length
обратно — значения не восстановятся:
1 |
var arr = [1, 2, 3, 4, 5]; |
2 |
3 |
arr.length = 2; // укоротить до 2 элементов |
4 |
alert(arr); // [1, 2] |
5 |
6 |
arr.length = 5; // вернуть length обратно, как было |
7 |
alert(arr[3]); // undefined: значения не вернулись |
Самый простой способ очистить массив — это arr.length=0
.
new Array
new Array()
Существует еще один синтаксис для создания массива:
var arr = new Array ( "Яблоко" , "Груша" , "и т.п." ); |
Он редко используется, т.к. квадратные скобки []
короче.
Кроме того, у него есть одна особенность. Обычно new Array(элементы, ...)
создает массив из данных элементов, но если у него один аргумент, и это число —то он создает массив без элементов, но с заданной длиной.
1 |
var arr = new Array(2,3); // создает массив [2, 3] |
2 |
3 |
arr = new Array(2); // создаст массив [2] ? |
4 |
5 |
alert(arr[0]); // нет! у нас массив без элементов, длины 2 |
Что же такое этот «массив без элементов, но с длиной»? Как такое возможно?
Оказывается, очень даже возможно и соответствует объекту {length: 2}
. Получившийся массив ведет себя так, как будто его элементы равны undefined
.
Это может быть неожиданным сюрпризом, поэтому обычно используют квадратные скобки.
Массивы в JavaScript могут содержать в качестве элементов другие массивы. Это можно использовать для создания многомерных массивов, например матриц:
1 |
var matrix = [ |
2 |
[1, 2, 3], |
3 |
[4, 5, 6], |
4 |
[7, 8, 9] |
5 |
]; |
6 |
7 |
alert(matrix[1][1]); // центральный элемент |
Эта секция относится ко внутреннему устройству структуры данных и требует специальных знаний. Она не обязательна к прочтению.
Числовые массивы, согласно спецификации, являются объектами, в которые добавили ряд свойств, методов и автоматическую длину length
. Но внутри они, как правило, устроены по-другому.
Современные интерпретаторы стараются оптимизировать их и хранить в памяти не в виде хэш-таблицы, а в виде непрерывной области памяти, так же как в языке C. Операции с массивами также оптимизируются, особенно если массив хранит только один тип данных, например только числа. Порождаемый набор инструкций для процессора получается очень эффективным.
Как правило, у интерпретатора это получается, но при этом программист не должен мешать.
В частности:
arr.test = 5
. То есть, работать именно как с массивом, а не как с объектом.arr[0]
, а потом сразу arr[1000]
, то он начинает работать с ним, как с обычным объектом. Как правило, это влечет преобразование его в хэш-таблицу.Если следовать этим принципам, то массивы будут занимать меньше памяти и быстрее работать.
Массивы существуют для работы с упорядоченным набором элементов.
Объявление:
1 |
// предпочтительное |
2 |
var arr = [ элемент1, элемент2... ]; |
3 |
4 |
// new Array |
5 |
var arr = new Array( элемент1, элемент2...); |
При этом new Array(число)
создает массив заданной длины, без элементов. Чтобы избежать ошибок, предпочтителен первый синтаксис.
Свойство length
— длина массива. Если точнее, то последний индекс массива плюс 1
. Если ее уменьшить вручную, то массив укоротится. Если length
больше реального количества элементов, то отсутствующие элементы равны undefined
.
Массив можно использовать как очередь или стек.
Операции с концом массива:
arr.push(элемент1, элемент2...)
добавляет элементы в конец.var elem = arr.pop()
удаляет и возвращает последний элемент.Операции с началом массива:
arr.unshift(элемент1, элемент2...)
добавляет элементы в начало.var elem = arr.shift()
удаляет и возвращает первый элемент.Эти операции перенумеровывают все элементы, поэтому работают медленно.
В следующей главе мы рассмотрим другие методы для работы с массивами.
К сожалению, в одной статье не просто дать все знания про массивы c числовыми индексами. Но я - старался. Если ты проявишь интерес к раскрытию подробностей,я обязательно напишу продолжение! Надеюсь, что теперь ты понял что такое массивы c числовыми индексами и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)
Комментарии
Оставить комментарий
Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)
Термины: Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)