Zindeksowane kolekcje

Zindeksowany zbiór to struktura danych, w której elementy są przechowywane i otwierane za pomocą indeksów numerowanych. Wartościami przechowywanymi w zindeksowanym zbiorze są numerowane indeksy, począwszy od 0, czyli wzorca o nazwie „zero indeksowania”. Następnie możesz uzyskać dostęp do wartości przechowywanych w zindeksowanej kolekcji, odwołując się do jej indeksów.

Tablica

Tablica to kontener, który może zawierać zero lub większą liczbę wartości dowolnego typu danych, w tym obiektów złożonych i innych tablic. Wartości przechowywane w tablicy są czasem nazywane „elementami” tablicy.

Tworzenie tablicy

Podobnie jak w przypadku podstawowych typów danych, tablicę można tworzyć na 2 sposoby: w postaci literału tablicy lub przez wywołanie wbudowanego w JavaScript konstruktora Array() z użyciem new Array(). Przypisanie tablicy do zmiennej to wysoce przenośny i uniwersalny sposób przypisywania wielu wartości do jednego identyfikatora.

Składnia literału tablicowego wykorzystuje zestaw nawiasów ([]) otaczających 0 lub więcej wartości danych rozdzielonych przecinkami:

const myArray = [];

Składnia konstruktora tablicowego wykorzystuje wbudowany w języka JavaScript obiekt Array jako konstruktor ze słowem kluczowym new:

const myArray = new Array();

Zarówno składnia literału tablicowego, jak i składni konstruktora tablicowego umożliwia wypełnianie tablicy informacjami podczas jej tworzenia, choć składnia nieco się różni pod względem definicji wartości. Składnia literału tablicowego wykorzystuje wartości w nawiasach kwadratowych rozdzielone przecinkami, co wygląda tak samo jak tablica wynikowa:

const myArray = [ true, null, "String", false ];

myArray;
> [ true, null, "String", false ]

Składnia konstruktora tablicowego przyjmuje jako argumenty wartości rozdzielone przecinkami z jednym specjalnym wyjątkiem:

const myArray = new Array( true, null, "String", false );

myArray;
> Array(4) [ true, null, "String", false ]

W przypadku przekazywania do konstruktora Array pojedynczej wartości liczbowej nie jest ona przypisywana do zerowej pozycji w tablicy wynikowej. Zamiast tego tworzona jest tablica z taką liczbą pustych przedziałów na wartości. Nie nakłada to żadnych ograniczeń na tablicę. Elementy można dodawać i usuwać w taki sam sposób jak w przypadku literału tablicy.

// Firefox:\
const myArray = new Array( 10 );

myArray;
> Array(10) [ <10 empty slots> ]
// Chrome:
const myArray = new Array( 10 );

myArray;
> (10) [empty × 10]

Tablice zawierające puste przedziały (czasami nazywane „rozproszonymi tablicami”) są uznawane za specjalne przypadki. Zamiast zawierać wartość undefined lub jawnie null, puste boksy są często, ale nie zawsze, traktowane jako wartości undefined w innych miejscach w języku.

Możesz przypadkowo utworzyć rozproszoną tablicę, korzystając ze składni literału tablicowego, pomijając wartość między przecinkami podczas tworzenia literału tablicy:

const myArray = [ true,, true, false ];

myArray;
> Array(4) [ true, <1 empty slot>, true, false ]

Chociaż pusty przedział nie jest traktowany jako istotna wartość we wszystkich kontekstach, jest wliczany do łącznej długości tablicy, co może prowadzić do nieoczekiwanych wyników podczas powtarzania wartości tablicy:

const myArray = [ 1,, 3, 4 ];

myArray.length;
> 4

for( const myValue of myArray ) {
  console.log( myValue + 10 );
}
> 11
> NaN
> 13
> 14

Takie zachowanie pozostało z niektórych wczesnych decyzji projektowych JavaScriptu. Unikaj korzystania z matryc rozproszonych w nowoczesnym środowisku programistycznym.

Podobnie jak w przypadku obiektów podstawowych, literał tablicy dziedziczy właściwości i metody z odpowiedniego konstruktora. Tablica jest specjalną formą obiektu, dlatego składnia literału tablicowego i składnia new Array() dają identyczne funkcjonalnie wyniki – obiekt, który dziedziczy prototyp z konstruktora Array.

const arrayLiteral = [];
const arrayConstructor = new Array();

typeof arrayLiteral;
> "object"

arrayLiteral;
> Array []
    length: 0
    <prototype>: Array []

typeof arrayConstructor;
> "object"

arrayConstructor;
> Array []
    length: 0
    <prototype>: Array []

Ponieważ 2 wyniki są identyczne, a składnia literału tablicowego jest bardziej zwięzła i dosłowna, dlatego zdecydowanie zalecamy, aby zawsze używać składni literału tablicy zamiast składni new Array().

Dostęp do wartości tablicy

Dostęp do poszczególnych elementów tablicy możesz uzyskać za pomocą notacji nawiasów, czyli zestawu nawiasów ([]) następujących po tablicy lub jej identyfikatorze, który zawiera liczbę odwołującą się do indeksu danego elementu:


[ "My string", "My other string" ][ 1 ];
> "My other string"

const myArray = [ "My string", 50, true ];

myArray[ 0 ];
> "My string"

myArray[ 1 ];
> 50

myArray[ 2 ];
> true

Tablice w języku JavaScript nie są powiązania, co oznacza, że nie możesz używać dowolnego ciągu jako indeksu. Jednak wartości liczbowe używane do uzyskiwania dostępu do elementów w tablicy są przekształcane w ciąg znaków, co oznacza, że możesz użyć ciągu znaków zawierającego tylko znaki liczbowe:

const myArray = [ "My string", 50, true ];

myArray[ 2 ];
> true

myArray[ "2" ];
> true

Próba uzyskania dostępu do elementu spoza zakresu zdefiniowanego w tablicy skutkuje wyświetleniem wyniku undefined, a nie błędu:

const myArray = [ "My string", 50, true ];

myArray[ 9 ];
> undefined

Demontowanie struktury przypisania

Demontaż przypisania to zwięzły sposób wyodrębniania zakresu wartości z tablic lub obiektów i przypisywania ich do zbioru identyfikatorów. Jest to proces nazywany „rozpakowywaniem” pierwotnej struktury danych, ale nie modyfikuje pierwotnej tablicy ani obiektu.

Przypisanie niszczenia do śledzenia wartości korzysta z listy identyfikatorów w postaci tablicy lub obiektów. W najprostszej postaci, czyli destrukturze wzorca wiązania, każda wartość jest wyodrębniona z tablicy lub obiektu i przypisana do odpowiedniej zmiennej, zainicjowana za pomocą let lub const (albo var):

const myArray = [ "A string", "A second string" ];
const [ myFirstElement, mySecondElement ] = myArray;

const myObject = { firstValue: false, secondValue: true };
const { myProp, mySecondProp } = myObject;

myFirstElement;
> "My string"

mySecondElement;
> "Second string"

myProp;
> false

mySecondProp;
> true

Nawiasy klamrowe ({}) pozwalają zdeformować obiekt, a nawiasy kwadratowe ([]) destrukturyzują tablicę.

const myArray = [ false, true ];
const myObject = { firstValue: false, secondValue: true };

const [ myProp, mySecondProp ] = myObject;
> Uncaught TypeError: myObject is not iterable

const { myElement, mySecondElement } = myArray;

myElement
> undefined

mySecondElement;
> undefined

Niszczenie tablicy odbywa się w kolejności od lewej do prawej. Każdy identyfikator w przypisaniu niszczyciela odpowiada elementowi tablicy o tym samym indeksie:

const myArray = [ 1, 2, 3 ];
const [ myElement, mySecondElement, myThirdElement ] = myArray;

myElement;
> 1

mySecondElement;
> 2

myThirdElement;
> 3

Jest to również domyślne zachowanie przy niszczeniu struktury obiektu. Jeśli jednak identyfikatory używane w przypisaniu do niszczenia struktury pasują do kluczy właściwości obiektu, są one wypełniane odpowiednimi wartościami właściwości niezależnie od ich kolejności:

const myObject = { firstValue: 1, secondValue: 2, thirdValue 3 };
const { secondValue, thirdValue, firstValue } = myObject;

firstValue;
> 1

secondValue;
> 2

thirdValue;
> 3

Elementy można pominąć, pomijając identyfikator:

const myArray = [ 1, 2, 3 ];
const [ firstValue,, secondValue ] = myArray;

firstValue;
> 1

secondValue;
> 3

Destrukturyzacja składni umożliwia też przypisanie wartości domyślnych, jeśli zdeorganizowana wartość jest pustym boksem (np. w przypadku rozproszonej tablicy) lub wartością undefined.

const myArray = [ true, ];
const [ firstValue = "Default string.", secondValue = "Default string." ] = myArray;

firstValue;
> true

secondValue;
> "Default string."

Dekonstrukcja nie przykuwa wartości do określonych typów. Oznacza to, że wartości „falsy”, takie jak puste ciągi ("") lub null, są nadal uznawane za istotne zdekonstruowane wartości:

const myArray = [ false, null, 0, "",, undefined ];
const [ falseValue = true, nullValue = true, zeroValue = true, emptyStringValue = true, emptySlot = true, undefinedValue = true ] = myArray;

falseValue;
> false;

nullValue;
> null

zeroValue;
> 0

emptyStringValue;
> ""

emptySlot;
> true

undefinedValue;
> true

Operator rozprzestrzeniania

Użycie operatora rozkładu (...) wprowadzonego w ES6 do rozszerzania iteracyjnej struktury danych, takiej jak tablica, ciąg znaków lub literał obiektu, do poszczególnych elementów. Po operatorze rozproszenia natychmiast znajduje się struktura danych do rozwinięcia lub identyfikator zmiennej zawierającej tę strukturę danych.

const myArray = [ 1, 2, 3 ];

console.log( ...myArray );
> 1 2 3

Składnia rozproszona jest używana głównie do kopiowania i łączenia tablic:

const myArray = [ 4, 5, 6 ];
const mySecondArray = [1, 2, 3, ...myArray ];

mySecondArray;
> Array(6) [ 1, 2, 3, 4, 5, 6 ]

Subskrypcji rozkładu można używać tylko w tych kontekstach:

W przypadku tablic i ciągów znaków składnia rozkładu ma zastosowanie tylko wtedy, gdy w wywołaniu funkcji lub elementach tablicy oczekuje zero lub więcej argumentów. Pierwszy przykład składni operatora rozproszonego w tej sekcji działa, ponieważ przekazuje ...myArray jako argument do wbudowanej metody console.log.

Na przykład nie można przypisać rozkładanych danych do zmiennej spoza innej tablicy:

const myArray = [ 1, 2, 3 ];
const spreadVariable = ...myArray;
> Uncaught SyntaxError: Unexpected token '...'

Jednak kopiujesz tablicę, rozpowszechniając jej pierwotną tablicę literał:

const myArray = [ 1, 2, 3 ];
const spreadArray = [ ...myArray ];

spreadArray;
> Array(3) [ 1, 2, 3 ]

Aby scalić elementy, które składają się na co najmniej 2 tablice, w jedną tablicę:

const myArray = [ 1, 2, 3 ];
const mySecondArray = [ 4, 5, 6 ];
const myNewArray = [ ...myArray, ...mySecondArray ];

myNewArray;
> Array(6) [ 1, 2, 3, 4, 5, 6 ]

Aby przekazać elementy tablicy jako poszczególne argumenty w wywołaniu funkcji:

const myArray = [ true, false ];
const myFunction = ( myArgument, mySecondArgument ) => {
    console.log( myArgument, mySecondArgument );
};

myFunction( ...myArray );
> true false

Operator rozprzestrzeniania się został rozszerzony do korzystania z literałów obiektów w ES2018 roku. Podobnie jak w przypadku tablic, za pomocą operatora rozkładu możesz powielać lub scalać obiekty:

const myObj = { myProperty : true };
const mySecondObj = { ...myObj };

mySecondObj;
> Object { myProperty: true }
const myFirstObj = { myProperty : true };
const mySecondObj = { additionalProperty : true };
const myMergedObj = { ...myFirstObj, ...mySecondObj };

myMergedObj;
> Object { myProperty: true, additionalProperty: true }

Operator rozkładu tworzy „płytkie” kopie. Oznacza to, że nie jest kopiowany prototyp oryginalnego obiektu ani jego nienumeryczne właściwości.

const myCustomPrototype = { protoProp: "My prototype." };
const myObj = Object.create( myCustomPrototype, {
    myEnumerableProp: {
        value: true,
        enumerable: true
    },
    myNonEnumerableProp: {
        value: false,
        enumerable: false
    }
});
const myNewObj = { ...myObj };

myObj;
> Object { myEnumerableProp: true, … }
    myEnumerableProp: true
    myNonEnumerableProp: false
    <prototype>: Object { protoProp: "My prototype." }

myNewObj;
> Object { myEnumerableProp: true }
    myEnumerableProp: true
    <prototype>: Object { … }

Pamiętaj, że tablic i obiektów nie można używać wymiennie. Nie można rozdzielić obiektu na tablicę ani dodać tablicy do obiektu.

Operator REST

Chociaż składnia samego operatora jest taka sama, operator reszty (...) wykonuje odwrotną funkcję na podstawie kontekstu, w którym jest używany. Zamiast rozszerzania iteracyjnej struktury danych na pojedyncze elementy, jak ma to miejsce w przypadku niszczenia przypisania lub jako parametru funkcji, operator reszta łączy te elementy w jedną strukturę danych. Jej nazwa wynika z faktu, że służy ona do zbierania „pozostałych” wartości danych.

W przypadku przypisania demontażu składni nosi ona nazwę „właściwość spoczynkowa”.

const myArray = [ "First", "Second", "Third", "Fourth", "Fifth" ];

[ myFirstElement, mySecondElement, ...remainingElements ] = myArray;

myFirstElement;
> "First"

mySecondElement;
> "Second"

remainingElements;
> Array(3) [ "Third", "Fourth", "Fifth"]

Gdy jest używana do podania nieokreślonej liczby argumentów dla funkcji, składnia nazywa się „parametrem spoczynkowym”:

function myFunction( ...myParameters ) {
    let result = 0;
    myParameters.forEach( ( myParam ) => {
        result += myParam;
    });
    return result;
};

myFunction( 2, 2 );
> 4

myFunction( 1, 1, 1, 10, 5 );
> 18

myFunction( 10, 11, 25 );
> 46

%TypedArray%

Tablice z typem to funkcja ES6 przeznaczona do przechowywania uporządkowanych danych binarnych, np. podczas pracy z przesłanymi plikami lub WebGL.

Tak jak w przypadku symboli, %TypedArray% funkcja wewnętrzna (zwykle udokumentowana jako %TypedArray% lub @@TypedArray, więc nie można jej pomylić z właściwością globalną) nie jest funkcją konstruktora w konwencjonalnym sensie i nie można wywołać jej bezpośrednio z użyciem new. Zamiast tego %TypedArray% odnosi się do nadrzędnej klasy nadrzędnej pojedynczych konstruktorów, z których każdy działa z określonym formatem danych binarnych. Wewnętrzna klasa nadrzędna %TypedArray% udostępnia właściwości i metody narzędziowe, które dziedziczą wszystkie podklasy konstruktora %TypedArray% i ich instancje.

Sprawdź swoją wiedzę

Biorąc pod uwagę argument „const myArray = [ 30, 50, 70 ];`, co zwraca argument „mytablica[1]”?

50
30
70

Jeśli argument „mojatablica” ma trzy wartości, co zwraca argument „mytablica[9]”?

Undefined
Komunikat o błędzie
9
Null