Тайная сила свойства array.length
Содержание:
- Идентификация массивов
- Методы, позволяющие работать с началом и концом массива
- Функции-«колбэки»
- slice
- JavaScript
- Инициализация массива в JavaScript
- Ширина/высота страницы с учётом прокрутки
- «Настоящие» массивы
- Javascript: работа с массивами
- reduce и reduceRight
- 7 — Typed Arrays and length
- More Examples
- 9 — Conclusion
- Методы Array
- Symbol.iterator
- JavaScript объекты
- reduce/reduceRight
- Методы pop/push, shift/unshift
Идентификация массивов
В процессе анализ кода у вас может возникнуть вопрос: является ли переменная массивом?
Проблема в том, что оператор JavaScript typeof возвращает , потому что массив JavaScript является объектом:
Выполнить код »
Скрыть результаты
Чтобы решить этот вопрос, стандарт ECMAScript 5 определяет новый метод :
Выполнить код »
Скрыть результаты
Проблема с этим решением заключается в том, что ECMAScript 5 не поддерживается в старых браузерах.
Узнать, является ли переменная массивом можно через пользовательскую функцию :
Выполнить код »
Скрыть результаты
И, наконец, оператор возвращает , если объект является массивом:
Выполнить код »
Скрыть результаты
Методы, позволяющие работать с началом и концом массива
В JavaScript предусмотрено 4 команды, которые позволяют добавлять и удалять элементы из начала и конца структурированных объектов.
Для начала расскажу вам о методах, работающих с началом массива. К ним относятся shift и unshift. Первая команда удаляет одно значение, а вторая добавляет.
В качестве примера я взял код предыдущей программы и видоизменил его.
1 2 3 4 5 6 7 8 |
var goods = ; document.writeln( goods ); //Говядина,Макароны,Твердый сыр,Специи document.writeln( goods ); //Твердый сыр goods.unshift("Томаты"); goods.unshift("Буженина"); document.writeln( goods ); //Буженина,Томаты,Говядина,Макароны,Твердый сыр,Специи goods.shift() document.writeln( goods ); //Томаты,Говядина,Макароны,Твердый сыр,Специи |
Теперь перейдем к методам, которые добавляют и удаляют элементы в конец списка. Так, pop отвечает за удаление значений, а push – за добавления.
К прошлой программной реализации допишем названные команды.
В результате на экран последней строкой будет выведено:
«Томаты,Говядина,Макароны,Твердый сыр,Итальянские травы».
Функции-«колбэки»
Рассмотрим ещё примеры функциональных выражений и передачи функции как значения.
Давайте напишем функцию с тремя параметрами:
- Текст вопроса
- Функция, которая будет вызываться, если ответ будет «Yes»
- Функция, которая будет вызываться, если ответ будет «No»
Наша функция должна задать вопрос и, в зависимости от того, как ответит пользователь, вызвать или :
На практике подобные функции очень полезны. Основное отличие «реальной» функции от примера выше будет в том, что она использует более сложные способы взаимодействия с пользователем, чем простой вызов . В браузерах такие функции обычно отображают красивые диалоговые окна. Но это уже другая история.
Аргументы функции ещё называют функциями-колбэками или просто колбэками.
Ключевая идея в том, что мы передаём функцию и ожидаем, что она вызовется обратно (от англ. «call back» – обратный вызов) когда-нибудь позже, если это будет необходимо. В нашем случае, становится колбэком’ для ответа «yes», а – для ответа «no».
Мы можем переписать этот пример значительно короче, используя Function Expression:
Здесь функции объявляются прямо внутри вызова . У них нет имён, поэтому они называются анонимными. Такие функции недоступны снаружи (потому что они не присвоены переменным), но это как раз то, что нам нужно.
Подобный код, появившийся в нашем скрипте выглядит очень естественно, в духе JavaScript.
Функция – это значение, представляющее «действие»
Обычные значения, такие как строки или числа представляют собой данные.
Функции, с другой стороны, можно воспринимать как «действия».
Мы можем передавать их из переменной в переменную и запускать, когда захотим.
slice
Есть три
основных метода для выделения подстрок из строки – это substring, substr и
slice. Метод slice имеет следующий
синтаксис:
str.slice(start )
и возвращает
часть строки от start до end (не включая его).
Например:
console.log( str.slice(, 5) ); //<span console.log( str.slice(6, 11) ); //class console.log( str.slice(12) ); //"clock"... console.log( str.slice(-7, -1) ); //</span
Следующий метод
str.substring(start )
работает
практически также как и slice, но здесь аргумент start может быть
больше, чем end, например:
console.log( str.substring(6, 11) ); //class console.log( str.substring(11, 6) ); //class
Но отрицательные
значения записывать нельзя, они будут трактоваться как 0.
Последний метод
str.substr(start )
Возвращает часть
строки, начиная с индекса start и длиной в length символов. В противоположность
предыдущим методам, здесь указывается длина вместо конечной позиции:
console.log( str.substr(6, 13) ); //class = "clock" console.log( str.substr(12) ); //"clock">12:34</span>
При
отрицательном значении первого аргумента позиция отсчитывается с конца строки.
Какой из этих
трех методов выбирать для выделения строк? По большому счету без разницы. Они
все работают эффективно, так что это дело предпочтения программиста.
JavaScript
JS Array
concat()
constructor
copyWithin()
entries()
every()
fill()
filter()
find()
findIndex()
forEach()
from()
includes()
indexOf()
isArray()
join()
keys()
length
lastIndexOf()
map()
pop()
prototype
push()
reduce()
reduceRight()
reverse()
shift()
slice()
some()
sort()
splice()
toString()
unshift()
valueOf()
JS Boolean
constructor
prototype
toString()
valueOf()
JS Classes
constructor()
extends
static
super
JS Date
constructor
getDate()
getDay()
getFullYear()
getHours()
getMilliseconds()
getMinutes()
getMonth()
getSeconds()
getTime()
getTimezoneOffset()
getUTCDate()
getUTCDay()
getUTCFullYear()
getUTCHours()
getUTCMilliseconds()
getUTCMinutes()
getUTCMonth()
getUTCSeconds()
now()
parse()
prototype
setDate()
setFullYear()
setHours()
setMilliseconds()
setMinutes()
setMonth()
setSeconds()
setTime()
setUTCDate()
setUTCFullYear()
setUTCHours()
setUTCMilliseconds()
setUTCMinutes()
setUTCMonth()
setUTCSeconds()
toDateString()
toISOString()
toJSON()
toLocaleDateString()
toLocaleTimeString()
toLocaleString()
toString()
toTimeString()
toUTCString()
UTC()
valueOf()
JS Error
name
message
JS Global
decodeURI()
decodeURIComponent()
encodeURI()
encodeURIComponent()
escape()
eval()
Infinity
isFinite()
isNaN()
NaN
Number()
parseFloat()
parseInt()
String()
undefined
unescape()
JS JSON
parse()
stringify()
JS Math
abs()
acos()
acosh()
asin()
asinh()
atan()
atan2()
atanh()
cbrt()
ceil()
clz32()
cos()
cosh()
E
exp()
expm1()
floor()
fround()
LN2
LN10
log()
log10()
log1p()
log2()
LOG2E
LOG10E
max()
min()
PI
pow()
random()
round()
sign()
sin()
sqrt()
SQRT1_2
SQRT2
tan()
tanh()
trunc()
JS Number
constructor
isFinite()
isInteger()
isNaN()
isSafeInteger()
MAX_VALUE
MIN_VALUE
NEGATIVE_INFINITY
NaN
POSITIVE_INFINITY
prototype
toExponential()
toFixed()
toLocaleString()
toPrecision()
toString()
valueOf()
JS OperatorsJS RegExp
constructor
compile()
exec()
g
global
i
ignoreCase
lastIndex
m
multiline
n+
n*
n?
n{X}
n{X,Y}
n{X,}
n$
^n
?=n
?!n
source
test()
toString()
(x|y)
.
\w
\W
\d
\D
\s
\S
\b
\B
\0
\n
\f
\r
\t
\v
\xxx
\xdd
\uxxxx
JS Statements
break
class
continue
debugger
do…while
for
for…in
for…of
function
if…else
return
switch
throw
try…catch
var
while
JS String
charAt()
charCodeAt()
concat()
constructor
endsWith()
fromCharCode()
includes()
indexOf()
lastIndexOf()
length
localeCompare()
match()
prototype
repeat()
replace()
search()
slice()
split()
startsWith()
substr()
substring()
toLocaleLowerCase()
toLocaleUpperCase()
toLowerCase()
toString()
toUpperCase()
trim()
valueOf()
Инициализация массива в JavaScript
В JavaScript мы можем создать пустой массив, применяя для этого квадратные скобки либо конструктор Array:
var users = new Array(); var people = []; console.log(users); // Array console.log(people); // Array
Кроме того, мы можем сразу же инициализировать наш массив некоторым числом элементов:
var users = new Array("Bill", "Tom", "Alice"); var people = "Sam", "John", "Kate"]; console.log(users); // console.log(people); //
Также можем определить массив, по ходу определяя в него новые элементы:
var users = new Array(); users1 = "Tom"; users2 = "Kate"; console.log(users1]); // "Tom" console.log(users]); // undefined
Обратите внимание, что не имеет значения, что массив по умолчанию создаётся с нулевой длиной. Используя индексы, мы сможем подставить тот или иной элемент на конкретный индекс в массиве
length
Если хотим узнать длину массива в JS, используем свойство length:
var fruit = new Array(); fruit = "груши"; fruit1 = "яблоки"; fruit2 = "сливы"; document.write("В массиве fruit " + fruit.length + " элемента: <br/>"); for(var i=; i < fruit.length; i++) document.write(fruiti + "<br/>");
Фактически, длиной нашего массива в JavaScript будет индекс последнего элемента, плюс единица. К примеру:
var users = new Array(); // в массиве 0 элементов users = "Kate"; users1 = "Tom"; users4 = "Sam"; for(var i=; i<users.length;i++) console.log(usersi]);
В этом случае вывод браузера будет следующим:
Kate Tom undefined undefined Sam
Вне зависимости от того, что для индексов №№ 2 и 3 мы элементов не добавляли, длиной массива будет число 5, ведь элементы с индексами №№ 2 и 3 будут просто иметь значение undefined.
Ширина/высота страницы с учётом прокрутки
Теоретически, видимая часть страницы – это , а полный размер с учётом прокрутки – по аналогии, .
Это верно для обычных элементов.
А вот для страницы с этими свойствами возникает проблема, когда прокрутка то есть, то нет. В этом случае они работают некорректно. В браузерах Chrome/Safari и Opera при отсутствии прокрутки значение в этом случае может быть даже меньше, чем , что, конечно же, выглядит как совершеннейшая чепуха и нонсенс.
Эта проблема возникает именно для , то есть для всей страницы.
Надёжно определить размер страницы с учётом прокрутки можно, взяв максимум из нескольких свойств:
Почему так? Лучше и не спрашивайте, это одно из редких мест, где просто ошибки в браузерах. Глубокой логики здесь нет.
«Настоящие» массивы
На них еще иногда говорят «массивы с числовыми индексами». Если сравнивать их с предыдущим вариантом, то здесь ключи представлены в виде чисел, а вот значения могут быть абсолютно любыми. Занесение коллекции в такой объект может быть осуществлено не по порядку.
Так, один элемент можно вписать в ячейку с индексом «0», а следующий – с индексом «4». Промежуточные ячейки памяти будут пустовать и выдавать «undefined», если к ним обратиться.
В качестве примера я написал небольшое приложение, в котором создан массив товаров.
1 2 3 4 5 |
var goods = ; alert( goods ); alert( goods ); goods = "Томаты" alert( goods ); |
Я специально показал вам, как вывести весь список покупок и как выбрать один элемент. К тому же я затронул свойство length, о котором конкретно расскажу позже. А пока дам небольшое пояснение.
Строка
Javascript: работа с массивами
Обращение или доступ к элементам массива в javaScript происходит так:
1 2 3 4 |
var mas=new Array(1,25,'Привет'); mas='Пока'; mas1=35; |
При инициализации массива элемент mas был равен 1. Затем мы изменили его значение на ‘Пока’. Значение элемента массива mas было изменено с 25 на 35.
Вывод элементов массива
При выводе значений массива в документ с помощью метода , его элементы выводятся через запятую:
1 2 |
var mas=new Array(1,25,'Привет'); document.write(mas) |
Результат:
1,25,Привет
- Рассмотрим, как осуществляется в javascript вывод массива с использованием обычного цикла :
1 2 3 4 5 6 7 |
var mas=new Array(1,25,'Привет'); function showElement(){ for(i=;i<3;i++) document.writeln(masi); } showElement(); |
Результат:
1 25 Привет
Использование цикла для перебора элементов массива:
1 2 3 4 5 6 7 8 |
var mas=new Array(1,25,'Привет'); function showElement(){ for(var i in mas){ document.writeln(masi); } } showElement(); |
Результат:
1 25 Привет
Задание array 5_1. Создать два массива: – с названием стран, и – с населением этих стран. Вывести название страны и ее население (использовать метод ).
Комментарии к выполнению:
- Вывод элементов массива оформить в виде функции.
- Сначала выполнить задание с помощью цикла , затем — с помощью цикла .
Задание array 5_2. Что выведет на экран следующий фрагмент кода?
var e = 1024; var table = e, e + 1, e + 2, e + 3; document.write(table); |
Пример: Что выведет на экран следующий фрагмент кода?
1 2 3 4 5 |
var arr = 1, 2, 3; arr5 = 5; for (var i = ; i < arr.length; i++) { document.write(arri + "<br />"); } |
В примере в строке происходит расширение массива – в 5-й индекс заносится значение . Цикл заполняет элементы типом , элементы которые мы не использовали — они остаются пустыми.
Удаление элементов массива
В javascript удалить элемент массива можно при помощи оператора :
1 2 3 |
var myColors = new Array("red", "green", "blue"); delete myColors1; alert(myColors); // red,,blue |
Задание array 5_3. Создать массив из трех элементов, значения элементов запрашивать у пользователя. Удалить второй по счету элемент, после чего вывести элементы массива на экран, каждый элемент с новой строки
reduce и reduceRight
Если нам нужно
перебрать массив – мы можем использовать forEach, for или for..of. Если нужно
перебрать массив и вернуть данные для каждого элемента – мы используем map.
Методы reduce и reduceRight
похожи на методы выше, но они немного сложнее и, как правило, используются для
вычисления какого-нибудь единого значения на основе всего массива.
Синтаксис:
let value =
ar.reduce(function(previousValue, item, index, array) {
// …
}, );
Функция
применяется по очереди ко всем элементам массива и «переносит» свой результат
на следующий вызов. Ее аргументы:
-
previousValue
– результат предыдущего вызова этой функции, равен initial при первом вызове
(если передан initial); -
item
– очередной элемент массива; -
index
– его индекс; -
array
– сам массив.
Например,
требуется вычислить сумму значений элементов массива. Это очень легко
реализовать этим методом, например, так:
let digs = 1, -2, 100, 3, 9, 54; let sum = digs.reduce((sum, current) => sum+current, ); console.log(sum);
Здесь значение sum при первом
вызове будет равно 0, так как мы вторым аргументом метода reduce указали 0 – это
начальное значение previousValue (то есть sum). Затем, на
каждой итерации мы будем иметь ранее вычисленное значение sum, к которому
прибавляем значение текущего элемента – current. Так и
подсчитывается сумма.
А вот примеры
вычисления произведения элементов массива:
let pr = digs.reduce((pr, current) => pr*current, 1); console.log(pr);
Здесь мы уже
указываем начальное значение 1, иначе бы все произведение было бы равно нулю.
Если начальное
значение не указано, то в качестве previousValue берется первый элемент массива
и функция стартует сразу со второго элемента. Поэтому во всех наших примерах
второй аргумент можно было бы и не указывать
Но такое использование требует
крайней осторожности. Если массив пуст, то вызов reduce без начального значения
выдаст ошибку:
let digs = ; let pr = digs.reduce((pr, current) => pr*current);
Поэтому, лучше
использовать начальное значение.
Метод
reduceRight работает аналогично, но проходит по массиву справа налево.
7 — Typed Arrays and length
When working with typed arrays the length property refers to the number of bit sized units the array is. For example if it is a Unit16Array and it has 3 elements the length of it is 3, and the byte length of it is 6.
12345678910111213 |
var a = ; var buff = Uint8Array.from(a); console.log(buff); console.log(buff.length); console.log(buff.byteLength); var buff = Uint16Array.from(a); console.log(buff); console.log(buff.length); console.log(buff.byteLength); |
The length of an array generally refers to the number of elements, or the highest index value plus one. It does not always refer to the the size of the array in terms of data.
More Examples
Example
Find out how many <p> elements there are inside a <div> element:
var div = document.getElementById(«myDIV»); // Get the <div> element with id=»myDIV»var nodelist = div.getElementsByTagName(«P»).length; // Get the number of <p> elements inside <div>
Example
Loop through all <p> elements inside a <div> element, and change the background color of each <p>:
var div = document.getElementById(«myDIV»);var nodelist = div.getElementsByTagName(«P»);var i;for (i = 0; i < nodelist.length; i++) { nodelist.style.backgroundColor = «red»;}
Example
Return the number of child nodes of the <body> element:
var nodelist = document.body.childNodes.length;
Example
Loop through the child nodes of <body> and output the node name of each child node:
var nodelist = document.body.childNodes;var txt = «»;var i;for (i = 0; i < nodelist.length; i++) { txt = txt + nodelist.nodeName + «<br>»;}
9 — Conclusion
So in javaScript array length is fairly easy to understand, but there are some things about it that can result in some confusion. There can be a difference between the length of an array and the actual element count for example. The length property is really only just a property of an object that reflects the highest element index of the array, and the array could be nothing but empty elements. There are also many little tricks about array length when it comes to setting the value of the length property of an array as a way to delete unwanted elements at the end of an array, and atypical ways of creating arrays fro plain old objects that juts have a length property.
In nay case I hope you enjoyed this post on array length in javaScript, I am sure that I have still managed to not cover everything when it comes to array length in javaScript alone, let alone the subject in general. If you have anything of relevant interest to add be sure to bring it up in the comments if you feel compelled to do so. Thank you for reading.
Методы Array
Метод | Описание |
---|---|
concat() | Метод для создания массива путем объединения нескольких массивов. Результат получается объединением массива, из которого вызывается метод с массивом или значениями, переданными аргументами методу. |
copyWithin() | Копирует элементы массива и вставляет их в тот же массив, заменяя определенные элементы массива (в зависимости от их индекса), длина массива при этом не изменяется. |
entries() | Возвращает объект итератор, который содержит пары ключ/значение по каждому индексу в массиве. |
every() | Возвращает , если каждый элемент в этом массиве удовлетворяет предоставленной функции тестирования. |
fill() | Заполняет все элементы массива одним значением, при необходимости задавая значение начального индекса с которого начинается заполнение и конечное значение индекса, которым заканчивается заполнение. |
filter() | Возвращает элементы массива, удовлетворяющие условию, указанному в функции обратного вызова. |
find() | Возвращает значение первого элемента в массиве, который соответствует условию в переданной функции, или , если ни один элемент не удовлетворяет условию в переданной функции. |
findIndex() | Возвращает индекс первого элемента в массиве, который соответствует условию в переданной функции. В противном случае возвращается -1. |
forEach() | Выполняет переданную функцию один раз для каждого элемента в массиве в порядке возрастания индекса. |
from() | Возвращает объект (массив) из любого объекта с свойством length или итерируемого объекта. |
includes() | Определяет, содержит ли массив определённый элемент, возвращая в зависимости от этого или . |
indexOf() | Возвращает первый индекс, по которому данный элемент может быть найден в массиве или -1, если такого индекса нет. |
isArray() | Проверяет, является ли переданный ему аргумент массивом. |
join() | Объединяет все элементы массива в строку и возвращает эту строку. По умолчанию разделителем является запятая (,), но метод позволяет задавать и другие разделители. |
keys() | Объединяет все элементы массива в строку и возвращает эту строку. По умолчанию разделителем является запятая (,), но метод позволяет задавать и другие разделители. |
lastIndexOf() | Возвращает последний индекс элемента внутри массива, эквивалентный указанному значению, или -1, если совпадений не найдено. |
map() | Создаёт новый массив с результатом вызова указанной функции для каждого элемента массива. |
pop() | Удаляет последний элемент из массива и возвращает этот элемент. |
push() | Добавляет один или несколько элементов в конец массива и возвращает новую длину массива. |
reduce() | Вызывает заданную функцию обратного вызова для всех элементов в массиве. Возвращаемое значение функции обратного вызова представляет собой накопленный результат и предоставляется как аргумент в следующем вызове функции обратного вызова. |
reduceRight() | Применяет заданную функцию обратного вызова к аккумулятору и каждому значению массива (справа-налево), сводя его к одному значению. |
reverse() | Изменяет порядок следования элементов в текущем массиве на обратный. |
shift() | Удаляет первый элемент из массива и возвращает этот элемент. |
slice() | Извлекает часть массива и возвращает новый массив. |
some() | Определяет, возвращает ли заданная функция обратного вызова значение для какого-либо элемента массива. |
sort() | Сортирует элементы массива. |
splice() | Изменяет текущий массив, добавляя или удаляя элементы. Возвращает массив с удаленными элементами, если элементы не удалялись, то возвращает пустой массив. |
toString() | Преобразует массив в строку и возвращает результат. |
unshift() | Добавляет один или несколько элементов в начало массива и возвращает новую длину массива. |
valueOf() | Возвращает примитивное значение объекта. |
Symbol.iterator
Мы легко поймём принцип устройства перебираемых объектов, создав один из них.
Например, у нас есть объект. Это не массив, но он выглядит подходящим для .
Например, объект , который представляет собой диапазон чисел:
Чтобы сделать итерируемым (и позволить работать с ним), нам нужно добавить в объект метод с именем (специальный встроенный , созданный как раз для этого).
- Когда цикл запускается, он вызывает этот метод один раз (или выдаёт ошибку, если метод не найден). Этот метод должен вернуть итератор – объект с методом .
- Дальше работает только с этим возвращённым объектом.
- Когда хочет получить следующее значение, он вызывает метод этого объекта.
- Результат вызова должен иметь вид , где означает, что итерация закончена, в противном случае содержит очередное значение.
Вот полная реализация с пояснениями:
Обратите внимание на ключевую особенность итераторов: разделение ответственности
- У самого нет метода .
- Вместо этого другой объект, так называемый «итератор», создаётся вызовом , и именно его генерирует значения.
Таким образом, итератор отделён от самого итерируемого объекта.
Технически мы можем объединить их и использовать сам как итератор, чтобы упростить код.
Например, вот так:
Теперь возвращает сам объект : у него есть необходимый метод , и он запоминает текущее состояние итерации в . Короче? Да. И иногда такой способ тоже хорош.
Недостаток такого подхода в том, что теперь мы не можем использовать этот объект в двух параллельных циклах : у них будет общее текущее состояние итерации, потому что теперь существует лишь один итератор – сам объект. Но необходимость в двух циклах , выполняемых одновременно, возникает редко, даже при наличии асинхронных операций.
Бесконечные итераторы
Можно сделать бесконечный итератор. Например, будет бесконечным при . Или мы можем создать итерируемый объект, который генерирует бесконечную последовательность псевдослучайных чисел. Это бывает полезно.
Метод не имеет ограничений, он может возвращать всё новые и новые значения, это нормально.
Конечно же, цикл с таким итерируемым объектом будет бесконечным. Но мы всегда можем прервать его, используя .
JavaScript объекты
Javascript — объектно-ориентированный язык. Это значит, что с некоторыми типами данных можно работать как с объектами, что позволяет применять к ним дополнительные функции для работы с объектами. К примеру, со строками можно работать и как с обычным типом данных и как с объектами:
// обычная строковая переменная myStr: var myStr = "Текст"; // создание строкового объекта myStr: var myStr = new String(); |
- Object(объекты)
- Number (обработка чисел)
- String (обработка строк)
- Array (массивы)
- Math (математические формулы, функции и константы)
- Date (работа с датами и временем)
- RegExp
- Global (его свойства Infinity, NaN, undefined)
- Function
Со всеми данными объектами мы познакомимся позже, с некоторыми из них мы частично уже знакомы.
Object — объект, который содержится во всех остальных объектах и обеспечивает их общую функциональность.
Объект function — функции являются объектами первого класса, т.е. могут присваиваться переменным, выступать аргументами других функций и быть результатом функций
Объявление новых объектов происходит одинаково, независимо от объекта (используется служебное слово new):
Как видно из примера, в javascript объявление массива происходит точно так же, как и у других объектов.
reduce/reduceRight
Метод «arr.reduce(callback)» используется для последовательной обработки каждого элемента массива с сохранением промежуточного результата.
Это один из самых сложных методов для работы с массивами. Но его стоит освоить, потому что временами с его помощью можно в несколько строк решить задачу, которая иначе потребовала бы в разы больше места и времени.
Метод используется для вычисления на основе массива какого-либо единого значения, иначе говорят «для свёртки массива». Чуть далее мы разберём пример для вычисления суммы.
Он применяет функцию по очереди к каждому элементу массива слева направо, сохраняя при этом промежуточный результат.
Аргументы функции :
- – последний результат вызова функции, он же «промежуточный результат».
- – текущий элемент массива, элементы перебираются по очереди слева-направо.
- – номер текущего элемента.
- – обрабатываемый массив.
Кроме , методу можно передать «начальное значение» – аргумент . Если он есть, то на первом вызове значение будет равно , а если у нет второго аргумента, то оно равно первому элементу массива, а перебор начинается со второго.
Проще всего понять работу метода на примере.
Например, в качестве «свёртки» мы хотим получить сумму всех элементов массива.
Вот решение в одну строку:
Разберём, что в нём происходит.
При первом запуске – исходное значение, с которого начинаются вычисления, равно нулю (второй аргумент ).
Сначала анонимная функция вызывается с этим начальным значением и первым элементом массива, результат запоминается и передаётся в следующий вызов, уже со вторым аргументом массива, затем новое значение участвует в вычислениях с третьим аргументом и так далее.
Поток вычислений получается такой
В виде таблицы где каждая строка – вызов функции на очередном элементе массива:
результат | |||
---|---|---|---|
первый вызов | |||
второй вызов | |||
третий вызов | |||
четвёртый вызов | |||
пятый вызов |
Как видно, результат предыдущего вызова передаётся в первый аргумент следующего.
Кстати, полный набор аргументов функции для включает в себя , то есть номер текущего вызова и весь массив , но здесь в них нет нужды.
Посмотрим, что будет, если не указать в вызове :
Результат – точно такой же! Это потому, что при отсутствии в качестве первого значения берётся первый элемент массива, а перебор стартует со второго.
Таблица вычислений будет такая же, за вычетом первой строки.
Метод arr.reduceRight работает аналогично, но идёт по массиву справа-налево.
Методы pop/push, shift/unshift
Очередь – один из самых распространённых вариантов применения массива. В области компьютерных наук так называется упорядоченная коллекция элементов, поддерживающая два вида операций:
- добавляет элемент в конец.
- удаляет элемент в начале, сдвигая очередь, так что второй элемент становится первым.
Массивы поддерживают обе операции.
На практике необходимость в этом возникает очень часто. Например, очередь сообщений, которые надо показать на экране.
Существует и другой вариант применения для массивов – структура данных, называемая стек.
Она поддерживает два вида операций:
- добавляет элемент в конец.
- удаляет последний элемент.
Таким образом, новые элементы всегда добавляются или удаляются из «конца».
Примером стека обычно служит колода карт: новые карты кладутся наверх и берутся тоже сверху:
Массивы в JavaScript могут работать и как очередь, и как стек. Мы можем добавлять/удалять элементы как в начало, так и в конец массива.
В компьютерных науках структура данных, делающая это возможным, называется двусторонняя очередь.
Методы, работающие с концом массива:
-
Удаляет последний элемент из массива и возвращает его:
-
Добавляет элемент в конец массива:
Вызов равнозначен .
Методы, работающие с началом массива:
-
Удаляет из массива первый элемент и возвращает его:
-
Добавляет элемент в начало массива:
Методы и могут добавлять сразу несколько элементов: