Jakie są najlepsze praktyki, których należy przestrzegać podczas deklarowania tablicy w JavaScript?

176

Kiedy muszę zadeklarować nową tablicę, używam tej notacji

var arr = new Array();

Ale podczas testowania w trybie online, na przykład na jsbin , ostrzeżenie sygnalizuje mi „Użyj notacji literału tablicy []”.

Nie znalazłem powodu, aby nie używać konstruktora. Czy w jakiś sposób jest mniej wydajne niż używanie []? A może to zła praktyka?

Czy jest dobry powód, aby używać var arr = [];zamiast var arr = new Array();?

Naigel
źródło
5
Obie są w porządku. Po prostu oszczędzasz trochę bajtów w transmisji.
Sirko,
13
Rzeczywiście istnieją różnice. Zobacz ten post: stackoverflow.com/q/2280285/921204
techfoobar
Uwaga: istnieją różnice, jeśli tablica została nadpisana tylko.
crdx
@apkd w niektórych przeglądarkach występuje znaczna różnica w wydajności
Alnitak
Słusznie. Nie widziałem tego w powiązanym pytaniu.
crdx,

Odpowiedzi:

260

Przeważnie ludzie używają, var a = []ponieważ Douglas Crockford tak mówi .

Jego powody obejmują nieintuicyjne i niespójne zachowanie new Array():

var a = new Array(5);     // an array pre-sized to 5 elements long
var b = new Array(5, 10); // an array with two elements in it

Zauważ, że nie ma sposobu, new Array()aby utworzyć tablicę zawierającą tylko jeden wstępnie określony element liczbowy!

Używanie []jest bardziej wydajne i bezpieczniejsze ! Możliwe jest nadpisanie Arraykonstruktora i wykonanie dziwnych rzeczy, ale nie można nadpisać zachowania [].

Osobiście zawsze używam []składni i podobnie zawsze używam {}składni zamiast new Object().

Alnitak
źródło
5
„nie można nadpisać zachowania []”. Jesteś tego pewien? Pomyślałem, że możesz nadpisać konstruktor Array, aby wpłynąć na [], i konstruktor Object, aby wpłynąć na {}, przynajmniej w niektórych implementacjach.
Random832
11
@ Random832 może być w starszych przeglądarkach, ale nie w implementacjach zgodnych z ES5, gdzie specyfikacja mówi, że []wywołuje wewnętrzny konstruktor, a nie jakąkolwiek wartość Array.constructor, która ma w danym momencie.
Alnitak
5
Bonus: literały tablicowe są znacznie szybsze niż tworzenie nowych tablic za pomocą Arraykonstruktora: jsperf.com/new-array
Mathias Bynens
@MathiasBynens tylko czasami.
OrangeDog,
Ew @ the [] działa inaczej z powodu wewnętrznego konstruktora. Niespójność spowoduje więcej zamieszania niż oszczędza. Edycja: Ach, troska o bezpieczeństwo. Rozumiem.
Erik Reppen
48

Jedną istotną różnicą jest to, że zawsze[] utworzy instancję nowego Array, podczas gdy może zostać przejęty w celu utworzenia innego obiektu .new Array

(function () {
    "use strict";
    var foo,
        bar;
    //don't do this, it's a bad idea
    function Array() {
        alert('foo');
    }
    foo = new Array();
    bar = [];
}());​

W moim przykładowym kodzie Arrayfunkcja została ukryta przed resztą zakresu dokumentu, jednak jest bardziej prawdopodobne, że jeśli kiedykolwiek napotkasz tego rodzaju problem, kod nie zostanie pozostawiony w ładnym zamknięciu i prawdopodobnie trudne do zlokalizowania.

Zastrzeżenie : nie jest dobrym pomysłem porywanie Arraykonstruktora.

zzzzBov
źródło
7
IIRC, w starszych przeglądarkach przesłanianie konstruktora Array również powodowałoby niepoprawną interpretację literałów. Jakiś czas temu istniała luka w zabezpieczeniach GMail CSRF, polegająca na zastępowaniu konstruktora tablicy, a nowe przeglądarki ignorują przeciążanie literałów właśnie z tego powodu.
hugomg
Zrzeczenie się odpowiedzialności: było jednak niezwykle pomocne i przydatne do ulepszania konstruktora Array na przestrzeni lat.
Erik Reppen
26

dla łatwości konserwacji użyj []

Literał tablicy jest bardziej przewidywalny, ponieważ używa go większość programistów. Większość używanych tablic będzie używać literału, a dopasowanie kodu do tego, czego używają inni programiści, ma wartość.

w przypadku pustych tablic użyj []

var ns = [];
var names = [ 'john', 'brian' ];

Jak pokazano tutaj , użycie literału pustego i kilku znanych elementów jest grubsze niż konstruktor Array.

dla tablicy o znanym rozmiarze użyj new Array(size)

Jeśli rozmiar jest znany, użycie konstruktora Array znacznie poprawia wydajność. Jednak oznacza to również, że musisz mieć do czynienia z tablicą, która ma już słowo „undefined” wypełniające wszystkie jej wartości.

Jak pokazano tutaj

// fill an array with 100 numbers
var ns = new Array( 100 );
for ( var i = 0; i < 100; i++ ) {
    ns[i] = i;
}

Działa to również w przypadku bardzo małych tablic .

JL235
źródło
12

Nie, właściwie nie ma powodu, aby używać jednej notacji zamiast drugiej dla pustych tablic.

Jednak większość przeglądarek wykazuje nieco lepszą wydajność przy użyciu x = [];niż wywołanie Konstruktora .

Jeśli chcesz utworzyć tablicę o określonym rozmiarze, musiszx = new Array(10); na przykład użyć , która utworzy tablicę z 10 undefinedgniazdami.

jAndy
źródło
@Alnitak: o którym już wspomniałeś, nie jest zbyt intuicyjny i zwięzły.
jAndy,
7
Stworzyłem jsperf, aby porównać wydajność: jsperf.com/array-constructor-versus-literal . Przynajmniej dla mnie na Chrome 20 na Ubuntu literał jest dwa razy szybszy niż konstruktor.
Steven,
1
@jAndy, przychodzi mi do głowy jedna różnica w przypadku pustych tablic .
zzzzBov,
jAndy, dlaczego chcesz mieć tablicę z „10 pustymi gniazdami” w JavaScript? W rzeczywistości możesz zrobić dokładnie to samo, używając: var arr = []; arr [9] = "omega"; 1. Tablice w JS są całkowicie dynamiczne, możesz odwoływać się do dowolnego indeksu, który chcesz, i będzie on po prostu „niezdefiniowany”. Jest to tak samo prawdziwe, jak gdybyś miał powiedzieć: var arr = new Array (10); arr [23]; 2. Długość tablicy zostanie ustawiona na najwyższą wartość, która zawiera cokolwiek w niej, niezależnie od tego, ile niezdefiniowanych szczelin jest pomiędzy nimi. Lub możesz to ustawić samodzielnie. [] może nie wyleczy raka, ale jest nieznacznie lepsze.
Norguard,
7
  • var arr = [] używa tablicy / literału obiektu
  • var arr = new Array () używa konstruktora tablicy / obiektu

Najszybszym sposobem zdefiniowania tablicy lub obiektu jest sposób dosłowny, ponieważ nie musisz wywoływać konstruktora

var arr1 = new Array(1, 2, 3, 4);
var arr2 = [1, 2, 3, 4];

alert(arr1[0]); // 1
alert(arr2[0]); // 1

var arr3 = new Array(200);
var arr4 = [200];

alert(arr3[0]); // 'undefined'
alert(arr4[0]); // 200
Yasir Mahmood
źródło
2
Dla odniesienia, za kulisami, var arr = [];logicznie również używa konstruktora. Jest to zawsze wbudowany konstruktor tablicy, a nie jakakolwiek funkcja o tej nazwie Array.
cHao
6

Oba są tylko poprawne. Ale większość ludzi używavar a = []

Trzy sposoby zadeklarowania tablicy w JavaScript.

metoda 1 : Możemy jawnie zadeklarować tablicę za pomocą słowa kluczowego JavaScript "new", aby utworzyć instancję tablicy w pamięci (tj. utworzyć ją i udostępnić).

// Declare an array (using the array constructor)
var arlene1 = new Array();
var arlene2 = new Array("First element", "Second", "Last");

metoda 2 : używamy alternatywnej metody do deklarowania tablic.

// Declare an array (using literal notation)
var arlene1 = [];
var arlene2 = ["First element", "Second", "Last"];

metoda 3 : JavaScript pozwala również pośrednio tworzyć tablice, wywołując określone metody.

// Create an array from a method's return value
var carter = "I-learn-JavaScript";
var arlene3 = carter.split("-");
BIEGŁ
źródło
4

Istnieje ograniczenie, które konstruktor może przyjąć jako argumenty.

W większości systemów, które napotkałem, limit wynosi 2 ^ 16 (2 bajty):

var myFreshArr = new Array(0,1,2,3 ..... 65536);

Spowoduje to błąd (za dużo argumentów ...)

Używając dosłownego [], nie masz takich problemów.

Jeśli nie dbasz o tak duże tablice, myślę, że możesz użyć tego, co wolisz.

Erwin Moller
źródło
2
Czy możesz podać przykład, w którym osoba mogłaby rozsądnie chcieć utworzyć tablicę wstępnie wypełnioną 70 000 wartościami? Chociaż to naprawdę wyjaśnia niektóre z okropnych stron internetowych, które widziałem, które nigdy się nie ładują ...
John O
2
John O, w swoich czasach widziałem kilka STRASZNYCH implementacji JSON, obejmujących tablice tablic 2D / 3D, w tym kody IATA (lotniska), linie lotnicze, touroperatorzy, ośrodki wypoczynkowe itd ... ... wszystkie nadziewane w jedną tablicę. To ... ... 1 MB + pliki do pobrania JSON sprawiają, że chcę płakać.
Norguard,
4
var array = [ 1, 2, 3, 4];

to cukier

var array = new Array(1, 2, 3, 4);

to sól

linquize
źródło
5
a gdzie go użyć, do kawy czy do makaronu?
Aristos,
cukier syntaktyczny i sól
linquize
3

To dlatego, że new Array()jest niejednoznaczne. Oto poprawne konstruktory:

// Using brackets
[element0, element1, ..., elementN]

// Using new AND a list of elements
new Array(element0, element1, ..., elementN)

// Using new AND an integer specifying the array length
new Array(arrayLength)
Florent
źródło