--- title: Indexed collections slug: Web/JavaScript/Guide/Indexed_collections translation_of: Web/JavaScript/Guide/Indexed_collections ---
У цьому розділ представлено набір даних, упорядкованих за значенням індексу. Це включає масиви та подібні до масиву конструкції, такі як об'єкти {{jsxref("Array")}} та {{jsxref("TypedArray")}} .
Об'єкт Array
Масив - це упорядкований набір значень, на який ви посилаєтесь з ім'ям та індексом.
Наприклад, розглянемо масив під назвою emp
, який містить імена працівників, індексовані їх числовим номером співробітника. Так emp[1]
буде працівником номер один, emp[2]
працівником номером два, тощо.
У JavaScript немає явного типу даних масиву. Однак ви можете використовувати заздалегідь заданий об’єкт Array
та його методи для роботи з масивами у ваших програмах. Об'єкт Array
має методи маніпулювання масивами різними способами, такими як з'єднання(joining), реверсування(reversing) та сортування. Він має властивість визначати довжину масиву та інші властивості для використання з регулярними виразами.
Наступні операції створюють еквівалентні масиви:
let arr = new Array(element0, element1, ..., elementN) let arr = Array(element0, element1, ..., elementN) let arr = [element0, element1, ..., elementN]
element0, element1, ..., elementN
- це список значень елементів масиву. Коли ці значення задані, масив ініціалізується з ними як елементами масиву. Властивість довжина (length)
масиву встановлюється рівною кількості аргументів.
Синтаксис дужки називається "літералом масиву" або "ініціалізатором масиву". Він коротший, ніж інші форми створення масиву, і тому загалом кращий. Докладніше див. Літерали масиву.
Для створення масиву з ненульовою довжиною, але без будь-яких елементів, може бути використане будь-яке з наведеного нижче:
// This... let arr = new Array(arrayLength) // ...буде такий саме масив як цей let arr = Array(arrayLength) // Це має точно такий же ефект let arr = [] arr.length = arrayLength
Примітка: У наведеному вище коді, arrayLength
повинен бути типу Number
. У іншому випадку, буде створений масив з єдиним елементом (з наданим значенням). Виклик arr.length
поверне arrayLength
, але масив у дійсності убде містити порожні (undefined) елементи. Запуск циклу {{jsxref("Statements/for...in","for...in")}} для масиву не поверне жодного з елементів масиву.
Крім нещодавно означеної змінної, як показано вище, масиви також можуть бути призначені як властивість для нового або існуючого об'єкта:
let obj = {} // ... obj.prop = [element0, element1, ..., elementN] // або let obj = {prop: [element0, element1, ...., elementN]}
Якщо Ви хочете ініціалізувати масив з єдиним елементом, а цей елемент є Number
, ви повинні використовувати синтаксис квадратних дужок. Коли одне значення Number
передається конструктору або функції Array()
, воно інтерпретується як arrayLength
, а не як окремий елемент.
let arr = [42] // Створює масив тільки з одним елементом: // числом 42. let arr = Array(42) // Створює масив без жодного елементу // і довжина масиву arr.length встановлена в 42. // // Це еквівалентно наступному: let arr = [] arr.length = 42
Виклик Array(N)
призводить до RangeError
, якщо N
- це не ціле число, тобто дробова частина якого не дорівнює нулю. Наступний приклад ілюструє таку поведінку.
let arr = Array(9.3) // RangeError: Invalid array length
Якщо ваш код потребує створення масивів з окремими елементами довільного типу даних, безпечніше використовувати літерали масиву. Крім того, спершу створіть порожній масив, перш ніж додати до нього один елемент.
У ES2015 ви можете використовувати статичний метод {{jsxref("Array.of")}} для створення масивів з одним елементом.
let wisenArray = Array.of(9.3) // wisenArray містить тільки один елемент 9.3
Ви можете заповнити масив, призначивши значення його елементам. Наприклад:
let emp = [] emp[0] = 'Casey Jones' emp[1] = 'Phil Lesh' emp[2] = 'August West'
Примітка: Якщо ви подасте неціле значення для оператора масиву в наведеному вище коді, буде створено властивість в об'єкті, що представляє масив, замість елемента масиву.
let arr = [] arr[3.4] = 'Oranges' console.log(arr.length) // 0 console.log(arr.hasOwnProperty(3.4)) // true
Ви також можете заповнити масив під час його створення:
let myArray = new Array('Hello', myVar, 3.14159) // або let myArray = ['Mango', 'Apple', 'Orange']
Ви звертаєтеся на елементи масиву, використовуючи порядковий номер елемента. Наприклад, припустимо, Ви означуєте такий масив:
let myArray = ['Wind', 'Rain', 'Fire']
Потім Ви звертаєтеся до першого елементу масиву як до myArray[0]
, а до другого елементу масиву як до myArray[1]
. Індекс елементів починається з нуля.
Примітка: Оператор масиву (квадратні дужки) також використовуються для доступу до властивостей масиву. (Масиви також є об'єктами в JavaScript). Наприклад:
let arr = ['one', 'two', 'three'] arr[2] // three arr['length'] // 3
На рівні реалізації масиви JavaScript фактично зберігають свої елементи як стандартні властивості об'єкта, використовуючи індекс масиву як ім'я властивості.
Властивість length
особлива. Вона завжди повертає індекс останнього елемента плюс один. (У наведеному нижче прикладі 'Dusty'
індексується на рівні 30, тому cats.length
повертає 30 + 1
).
Пам'ятайте, що індекси масиву JavaScript базуються на 0: вони починаються з 0
, а не 1
. Це означає, що властивість length
буде на один більше, ніж найвищий індекс, що зберігається в масиві:
let cats = [] cats[30] = ['Dusty'] console.log(cats.length) // 31
Ви також можете записати значення у властивість length
.
Введення значення, коротшого за кількість збережених елементів, скорочує масив. Написання 0
спустошує масив повністю:
let cats = ['Dusty', 'Misty', 'Twiggy'] console.log(cats.length) // 3 cats.length = 2 console.log(cats) // logs "Dusty, Misty" - Twiggy видалено cats.length = 0 console.log(cats) // logs []; масив cats array - порожній cats.length = 3 console.log(cats) // logs [ <3 пустих елементи> ]
Поширена операція - це перебір значень масиву, з обробкою кожного елементу. Найпростіший спосіб зробити це наступним чином:
let colors = ['red', 'green', 'blue'] for (let i = 0; i < colors.length; i++) { console.log(colors[i]) }
Якщо ви знаєте, що жоден з елементів вашого масиву не повертає false
в булевому контексті, наприклад, якщо ваш масив складається з вузлів DOM, Ви можете використовувати більш ефективну ідіому:
let divs = document.getElementsByTagName('div') for (let i = 0, div; div = divs[i]; i++) { /* Process div in some way */ }
Це дозволяє уникнути накладних перевірок довжини масиву та гарантує, що змінна div
для додаткової зручності переназначається поточному елементу на кожній ітерації .
Метод {{jsxref("Array.forEach", "forEach()")}} забезпечує інший спосіб ітерації з масивом:
let colors = ['red', 'green', 'blue'] colors.forEach(function(color) { console.log(color) }) // red // green // blue
Крім того, ви можете скоротити код для параметра forEach за допомогою функції стрілок ES2015:
let colors = ['red', 'green', 'blue'] colors.forEach(color => console.log(color)) // red // green // blue
Функція, передана forEach
, виконується один раз для кожного елемента масиву, при цьому елемент масиву передається як аргумент функції. Не присвоєні значення не перебираються в циклі forEach
.
Зауважте, що елементи масиву, опущені при означенні масиву, не перебираються під час ітерації forEach
, але пеербираються, коли вручну елемнту було присвоєно undefined
:
let array = ['first', 'second', , 'fourth'] array.forEach(function(element) { console.log(element) }) // first // second // fourth if (array[2] === undefined) { console.log('array[2] is undefined') // true } array = ['first', 'second', undefined, 'fourth'] array.forEach(function(element) { console.log(element) }) // first // second // undefined // fourth
Оскільки елементи JavaScript зберігаються як стандартні властивості об'єкта, не рекомендується проводити повторення через масиви JavaScript, використовуючи цикли {{jsxref("Statements/for...in","for...in")}} , оскільки будуть перебрані як нормальні елементи так і всі властивості масиву.
Об'єкт {{jsxref("Array")}} має наступні методи:
{{jsxref("Array.concat", "concat()")}} з'єднує два або більше масива і повертає новий масив.
let myArray = new Array('1', '2', '3') myArray = myArray.concat('a', 'b', 'c') // myArray тепер такий ["1", "2", "3", "a", "b", "c"]
{{jsxref("Array.join", "join(delimiter = ',')")}} об'єднує всі елементи масиву в рядок.
let myArray = new Array('Wind', 'Rain', 'Fire') let list = myArray.join(' - ') // list є "Wind - Rain - Fire"
{{jsxref("Array.push", "push()")}} додає один або більше елементів в кінець масиву і повертає отриману довжину length
масиву.
let myArray = new Array('1', '2') myArray.push('3') // myArray тепер ["1", "2", "3"]
{{jsxref("Array.pop", "pop()")}} видаляє останній елемент з масиву і повертає цей елемент.
let myArray = new Array('1', '2', '3') let last = myArray.pop() // myArray тепер ["1", "2"], last = "3"
{{jsxref("Array.shift", "shift()")}} видаляє перший елемент з масиву і повертає цей елемент.
let myArray = new Array('1', '2', '3') let first = myArray.shift() // myArray тепер ["2", "3"], first є "1"
{{jsxref("Array.unshift", "unshift()")}} додає один або більше елементів до передньої частини масиву і повертає нову довжину масиву.
let myArray = new Array('1', '2', '3') myArray.unshift('4', '5') // myArray став ["4", "5", "1", "2", "3"]
{{jsxref("Array.slice", "slice(start_index, upto_index)")}} виймає частину масиву і повертає новий масив.
let myArray = new Array('a', 'b', 'c', 'd', 'e') myArray = myArray.slice(1, 4) // починаючи з 1-го вимйає елементи до 4-го // повертає [ "b", "c", "d"]
{{jsxref("Array.splice", "splice(index, count_to_remove, addElement1, addElement2, ...)")}} видаляє елементи з масиву та (необов'язково) замінює їх. Він повертає елементи, вилучені з масиву.
let myArray = new Array('1', '2', '3', '4', '5') myArray.splice(1, 3, 'a', 'b', 'c', 'd') // myArray тепер ["1", "a", "b", "c", "d", "5"] // Цей код стартує з першого індексу (or where the "2" was), // видаляє 3 елементи, а тоді вставляє всі підряд // на це місце.
{{jsxref("Array.reverse", "reverse()")}} транспонує масив: перший елемент масиву стає останнім, а останній стає першим. Він повертає посилання на масив.
let myArray = new Array('1', '2', '3') myArray.reverse() // транспонований масив myArray = ["3", "2", "1"]
{{jsxref("Array.sort", "sort()")}} сортує елементи масиву на місці та повертає посилання на масив.
let myArray = new Array('Wind', 'Rain', 'Fire') myArray.sort() // відсортований масив myArray = ["Fire", "Rain", "Wind"]
sort()
також може скористатися функцією зворотного виклику для визначення порівняння елементів масиву.
Метод sort
(та інші нижче), які приймають функцію зворотного виклику, відомі як ітераційні методи, оскільки певним чином вони перебирають весь масив. Кожен з них бере необов'язковий другий аргумент під назвою thisObject
. Якщо thisObject
передається, він стає значенням ключового слова this
всередині тіла функції зворотного виклику. Якщо це не передбачено, як і в інших випадках, коли функція викликається поза явним контекстом об'єкта, this
стосуватиметься глобального об'єкта (window
) при використанні функції вказівника зворотного виклику, або undefined
при використанні нормальної функції зворотного виклику.
Функція зворотного виклику викликається двома аргументами, які є елементами масиву.
Функція нижче порівнює два значення і повертає одне з трьох значень:
Наприклад, наступне буде сортувати за останньою літерою рядка:
let sortFn = function(a, b) { if (a[a.length - 1] < b[b.length - 1]) return -1; if (a[a.length - 1] > b[b.length - 1]) return 1; if (a[a.length - 1] == b[b.length - 1]) return 0; } myArray.sort(sortFn) // відсортований масив myArray = ["Wind","Fire","Rain"]
a
за системою сортування менше b
, поверне -1
(або будь-яке від’ємне число)a
за системою сортування більше, ніж b
, поверне 1
(або будь-яке додатне число)a
і b
вважати еквівалентними, поверне 0
.{{jsxref("Array.indexOf", "indexOf(searchElement[, fromIndex])")}} шукає масив для searchElement
та повертає індекс першого збігу.
let a = ['a', 'b', 'a', 'b', 'a'] console.log(a.indexOf('b')) // пише 1 // Тепер спробуйте ще раз, починаючи з останнього співпадіння console.log(a.indexOf('b', 2)) // пише 3 console.log(a.indexOf('z')) // пише -1, оскільки 'z' не було знайдено
{{jsxref("Array.lastIndexOf", "lastIndexOf(searchElement[, fromIndex])")}} працює як indexOf
, але починає з кінця і шукає у зворотному порядку.
let a = ['a', 'b', 'c', 'd', 'a', 'b'] console.log(a.lastIndexOf('b')) // пише 5 // Тепер спробуйте ще раз, починаючи з останнього співпадіння console.log(a.lastIndexOf('b', 4)) // пише 1 console.log(a.lastIndexOf('z')) // пише -1
{{jsxref("Array.forEach", "forEach(callback[, thisObject])")}} виконує callback
на кожному елементі масиву і повертає undefined
.
let a = ['a', 'b', 'c'] a.forEach(function(element) { console.log(element) }) // logs each item in turn
{{jsxref("Array.map", "map(callback[, thisObject])")}} повертає новий масив повернутого значення при виконанні зворотного виклику callback
на кожному елементі масиву.
let a1 = ['a', 'b', 'c'] let a2 = a1.map(function(item) { return item.toUpperCase() }) console.log(a2) // logs ['A', 'B', 'C']
{{jsxref("Array.filter", "filter(callback[, thisObject])")}} повертає новий масив, що містить елементи, для яких callback
повернув true
.
let a1 = ['a', 10, 'b', 20, 'c', 30] let a2 = a1.filter(function(item) { return typeof item === 'number'; }) console.log(a2) // logs [10, 20, 30]
{{jsxref("Array.every", "every(callback[, thisObject])")}} повертає true
, якщо callback
повертає true
для кожного елемента масиву.
function isNumber(value) { return typeof value === 'number' } let a1 = [1, 2, 3] console.log(a1.every(isNumber)) // logs true let a2 = [1, '2', 3] console.log(a2.every(isNumber)) // logs false
{{jsxref("Array.some", "some(callback[, thisObject])")}} повертає true
, якщо callback
повертає true
для принаймні одного елемента в масиві.
function isNumber(value) { return typeof value === 'number' } let a1 = [1, 2, 3] console.log(a1.some(isNumber)) // logs true let a2 = [1, '2', 3] console.log(a2.some(isNumber)) // logs true let a3 = ['1', '2', '3'] console.log(a3.some(isNumber)) // logs false
{{jsxref("Array.reduce", "reduce(callback[, initialValue])")}} застосовує callback(accumulator, currentValue[, currentIndex[, array]])
для кожного значення масиву з метою зменшення списку елементів до одного значення. Функція зменшення повертає кінцеве значення, повернене функцією callback
.
Якщо вказано initialValue
, тоді callback
викликається initialValue
як значення першого параметра, а значення першого елемента в масиві - як значення другого параметра.
Якщо initialValue
не вказана, першими двома параметрами callback
будуть перший і другий елементи масиву. При кожному наступному виклику значенням першого параметра буде будь-який callback
, повернутий при попередньому виклику, а значення другого параметра буде наступним значенням масиву.
Якщо для callback
потрібен доступ до індексу оброблюваного елемента, для доступу до всього масиву вони доступні як необов'язкові параметри.
let a = [10, 20, 30] let total = a.reduce(function(accumulator, currentValue) { return accumulator + currentValue }, 0) console.log(total) // Prints 60
{{jsxref("Array.reduceRight", "reduceRight(callback[, initialValue])")}} працює подібно reduce()
, але починається з останнього елемента.
reduce
та reduceRight
- найменш очевидний із ітеративних методів масиву. Їх слід використовувати для алгоритмів, що поєднують два значення рекурсивно, щоб зменшити послідовність до одного значення.
Масиви можуть бути вкладені, тобто масив може містити інший масив як елемент. Використовуючи цю характеристику масивів JavaScript, можна створити багатовимірні масиви.
Наступний код створює багатовимірний масив.
let a = new Array(4) for (let i = 0; i < 4; i++) { a[i] = new Array(4) for (let j = 0; j < 4; j++) { a[i][j] = '[' + i + ', ' + j + ']' } }
Цей приклад створює масив із таких рядків:
Row 0: [0, 0] [0, 1] [0, 2] [0, 3] Row 1: [1, 0] [1, 1] [1, 2] [1, 3] Row 2: [2, 0] [2, 1] [2, 2] [2, 3] Row 3: [3, 0] [3, 1] [3, 2] [3, 3]
Коли масив є результатом збігу між регулярним виразом і рядком, масив повертає властивості та елементи, які надають інформацію про збіг. Масив - це повернене значення {{jsxref("Global_Objects/RegExp/exec","RegExp.exec()")}}, {{jsxref("Global_Objects/String/match","String.match()")}}, і {{jsxref("Global_Objects/String/split","String.split()")}}. Інформацію про використання масивів з регулярними виразами див Regular Expressions.
Деякі об`єкти JavaScript, такі як NodeList
повертають document.getElementsByTagName()
або об'єкт {{jsxref("Functions/arguments","arguments")}}, доступний в тілі функції, який виглядає і поводиться як масиви на поверхні, але не ділиться всіма їх методами. Наприклад, об'єкт arguments
забезпечує атрибут {{jsxref("Global_Objects/Function/length","length")}} але не реалізує метод {{jsxref("Array.forEach", "forEach()")}}.
Методи прототипу масиву можна викликати для інших об’єктів, подібних до масиву. наприклад:
function printArguments() { Array.prototype.forEach.call(arguments, function(item) { console.log(item) }) }
Методи прототипу масиву також можна використовувати і для рядків, оскільки вони забезпечують послідовний доступ до своїх символів аналогічно масивам:
Array.prototype.forEach.call('a string', function(chr) { console.log(chr) })
JavaScript typed arrays є схожими на масив об'єктів і забезпечують механізм доступу до необроблених бінарних даних. Як ви вже знаєте, об'єкт {{jsxref("Array")}} динамічно росте і скорочується і може мати будь-яке значення JavaScript. Рушії JavaScript виконують оптимізацію, щоб ці масиви були швидкими. Однак, оскільки веб-застосунки стають все більш потужними, додаючи такі функції, як маніпулювання аудіо та відео, доступ до необроблених даних за допомогою WebSockets тощо, стало зрозуміло, що є випадки, коли корисним буде код JavaScript для швидкого та легкого маніпулювати необробленими бінарними даними в типізованих масивах.
Щоб досягти максимальної гнучкості та ефективності, JavaScript типізовані масиви розділили реалізацію на буфери (buffers) та представлення(views). Буфер (реалізований об'єктом {{jsxref ("ArrayBuffer")}}) - це об'єкт, що представляє фрагмент даних; він не має формату, про який можна говорити, і не пропонує механізму доступу до його вмісту. Для доступу до пам'яті, що міститься в буфері, вам потрібно скористатися представленням. Представлення забезпечує контекст - тобто тип даних, початкове зміщення та кількість елементів - який перетворює дані у фактично набраний масив.
{{jsxref("ArrayBuffer")}} - це тип даних, який використовується для репрезентації загального буфера даних бінарних даних фіксованої довжини. Ви не можете безпосередньо маніпулювати вмістом ArrayBuffer
; натомість ви створюєте типізоване представлення масиву або {{jsxref("DataView")}} який представляє буфер у певному форматі, і використовують його для читання та запису вмісту буфера.
Типізовані представлення масивів мають самостійно описові назви та надають представлення для всіх звичайних числових типів, таких як Int8
, Uint32
, Float64
і так далі. Існує один спеціальний вид типізованого представлення масиву Uint8ClampedArray
. Він фіксує значення між 0
та 255
. Це корисно, наприклад, для обробки даних Canvas.
Type | Value Range | Size in bytes | Description | Web IDL type | Equivalent C type |
---|---|---|---|---|---|
{{jsxref("Int8Array")}} | -128 to 127 |
1 | 8-bit two's complement signed integer | byte |
int8_t |
{{jsxref("Uint8Array")}} | 0 to 255 |
1 | 8-bit unsigned integer | octet |
uint8_t |
{{jsxref("Uint8ClampedArray")}} | 0 to 255 |
1 | 8-bit unsigned integer (clamped) | octet |
uint8_t |
{{jsxref("Int16Array")}} | -32768 to 32767 |
2 | 16-bit two's complement signed integer | short |
int16_t |
{{jsxref("Uint16Array")}} | 0 to 65535 |
2 | 16-bit unsigned integer | unsigned short |
uint16_t |
{{jsxref("Int32Array")}} | -2147483648 to 2147483647 |
4 | 32-bit two's complement signed integer | long |
int32_t |
{{jsxref("Uint32Array")}} | 0 to 4294967295 |
4 | 32-bit unsigned integer | unsigned long |
uint32_t |
{{jsxref("Float32Array")}} | 1.2 ×10-38 to 3.4 ×1038 |
4 | 32-bit IEEE floating point number (7 significant digits e.g., 1.1234567 ) |
unrestricted float |
float |
{{jsxref("Float64Array")}} | 5.0 ×10-324 to 1.8 ×10308 |
8 | 64-bit IEEE floating point number (16 significant digits e.g., 1.123...15 ) |
unrestricted double |
double |
{{jsxref("BigInt64Array")}} | -263 to 263-1 |
8 | 64-bit two's complement signed integer | bigint |
int64_t (signed long long) |
{{jsxref("BigUint64Array")}} | 0 to 264-1 |
8 | 64-bit unsigned integer | bigint |
uint64_t (unsigned long long) |
For more information, see JavaScript typed arrays and the reference documentation for the different {{jsxref("TypedArray")}} objects.
{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Keyed_Collections")}}