Quais são as práticas recomendadas a seguir ao declarar uma matriz em Javascript?

176

Quando preciso declarar uma nova matriz, uso esta notação

var arr = new Array();

Porém, ao testar on-line, por exemplo, no jsbin , um aviso indica que "Use a notação literal da matriz []".

Não encontrei um motivo para evitar o uso do construtor. De alguma forma, é menos eficiente do que usar []? Ou é uma má prática?

Existe uma boa razão para usar em var arr = [];vez de var arr = new Array();?

Naigel
fonte
5
Ambos estão bem. Você acabou de salvar alguns bytes na transmissão.
Sirko
13
De fato, existem diferenças. Veja esta postagem: stackoverflow.com/q/2280285/921204
techfoobar 16/12/12
Nota: existem diferenças se a matriz tiver sido substituída apenas.
Crdx
@apkd em alguns navegadores há uma diferença significativa de desempenho
Alnitak
Justo. Não vi isso na questão vinculada.
Crdx

Respostas:

260

Principalmente , as pessoas usam var a = []porque Douglas Crockford diz isso .

Suas razões incluem o comportamento não intuitivo e inconsistente de 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

Observe que não há como new Array()criar uma matriz com apenas um elemento numérico pré-especificado!

Usar []é realmente mais eficiente e mais seguro também ! É possível sobrescrever o Arrayconstrutor e fazê-lo fazer coisas estranhas, mas você não pode sobrescrever o comportamento de [].

Pessoalmente, eu sempre uso a []sintaxe e da mesma forma sempre uso a {}sintaxe no lugar de new Object().

Alnitak
fonte
5
"você não pode substituir o comportamento de []." Você tem certeza disso? Eu pensei que você poderia substituir o construtor Array para afetar [] e o construtor Object para afetar {}, pelo menos em algumas implementações.
Random832
11
@ Random832 talvez em navegadores mais antigos, mas não em implementações compatíveis com ES5, onde a especificação diz que []chama um construtor interno, e não o valor Array.constructorque tiver naquele momento.
Alnitak
5
Bônus: literais de matriz são muito mais rápidos do que criar novas matrizes usando o Arrayconstrutor: jsperf.com/new-array
Mathias Bynens
@MathiasBynens apenas às vezes.
18264 OrangeDog
Ew @ the [] trabalhando de maneira diferente por causa do construtor interno. A inconsistência causará mais confusão do que salva. Edit: Ah, preocupação de segurança. Entendi.
Erik Reppen
48

Uma diferença significativa é que []vai sempre instanciar um novo Array, enquanto que new Arraypoderia ser sequestrado para criar um objeto diferente .

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

No meu exemplo de código, eu mantive a Arrayfunção oculta do restante do escopo do documento, no entanto, é mais provável que, se você se deparar com esse tipo de problema, o código não tenha sido deixado em um bom fechamento e provavelmente será difícil de localizar.

Isenção de responsabilidade : não é uma boa idéia seqüestrar o Arrayconstrutor.

zzzzBov
fonte
7
IIRC, em navegadores mais antigos, substituindo o construtor Array, também faria com que literais fossem interpretados incorretamente. Há uma vulnerabilidade no GMail CSRF há algum tempo, os envolvidos substituíram o construtor da matriz e os novos navegadores ignoram a sobrecarga de literais por esse motivo preciso.
23912 hugomg
Contra-renúncia: no entanto, tem sido extremamente útil e útil para aprimorar o construtor Array ao longo dos anos.
Erik Reppen
26

para manutenção, use []

O literal da matriz é mais previsível, como a maioria dos desenvolvedores usa. A maior parte do uso de matrizes por aí estará usando o literal, e há um valor em ter seu código compatível com o que outros desenvolvedores usam.

para matrizes vazias, use []

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

Como mostrado aqui , o uso do literal para vazio e alguns elementos conhecidos é mais interessante que o construtor Array.

para uma matriz de tamanho conhecido, use new Array(size)

Se o tamanho for conhecido, o uso do construtor Array melhora significativamente o desempenho. No entanto, isso também significa que você precisa lidar com uma matriz que já tenha 'indefinido' preenchendo todos os seus valores.

Como mostrado aqui

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

Isso também funciona para matrizes muito pequenas .

JL235
fonte
12

Não, na verdade não há razão para usar uma notação sobre a outra para matrizes vazias.

No entanto, a maioria dos navegadores mostra um desempenho um pouco melhor usando do x = [];que chamar o Construtor .

Se você precisar criar uma matriz com um tamanho específico, precisará usar, x = new Array(10);por exemplo, o que criaria uma matriz com 10 undefinedslots.

jAndy
fonte
@ Alnitak: que você já mencionou, não é muito intuitivo e conciso.
Jandy
7
Eu montei um jsperf para comparar o desempenho: jsperf.com/array-constructor-versus-literal . Pelo menos para mim no Chrome 20 no Ubuntu, o literal é duas vezes mais rápido que o construtor.
Steven
jAndy, por que você deseja uma matriz com "10 slots vazios" em JavaScript? Na realidade, você pode fazer exatamente a mesma coisa com: var arr = []; arr [9] = "ômega"; 1. Matrizes em JS são totalmente dinâmicas, você pode fazer referência a qualquer índice que desejar e será apenas "indefinido". Isso é tão verdadeiro como se você dissesse: var arr = new Array (10); arr [23]; 2. o comprimento da matriz será definido como o valor mais alto que possui algo, independentemente de quantos slots indefinidos estejam no meio. Ou você pode configurá-lo você mesmo. [] pode não curar o câncer, mas é marginalmente melhor.
Norguard 17/07/12
7
  • var arr = [] usa a matriz / objeto literal
  • var arr = new Array () usa o construtor array / objeto

A maneira mais rápida de definir uma matriz ou objeto é literal, porque você não precisa chamar o construtor

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
fonte
2
Para referência, nos bastidores, também var arr = [];usa logicamente um construtor. É sempre sempre o construtor de matriz embutido, em vez de qualquer função que esteja sendo usada atualmente pelo nome Array.
cHao 16/07/12
6

Ambos estão corretos apenas. Mas a maioria das pessoas usavar a = []

Três maneiras de declarar uma matriz em JavaScript.

método 1 : podemos declarar explicitamente um array com a palavra-chave "new" JavaScript para instanciar o array na memória (por exemplo, criá-lo e disponibilizá-lo).

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

método 2 : usamos um método alternativo para declarar matrizes.

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

método 3 : JavaScript também permite criar matrizes indiretamente, chamando métodos específicos.

// Create an array from a method's return value
var carter = "I-learn-JavaScript";
var arlene3 = carter.split("-");
CORREU
fonte
4

Há um limite que o construtor pode usar como argumento.

Na maioria dos sistemas que encontrei, o limite é 2 ^ 16 (2 bytes):

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

Isso causará um erro (muitos argumentos ....)

Ao usar o literal [], você não tem esses problemas.

Caso você não se importe com matrizes tão grandes, acho que você pode usar o que preferir.

Erwin Moller
fonte
2
Você pode citar um exemplo de onde uma pessoa pode razoavelmente querer criar uma matriz previamente preenchida com 70.000 valores? Embora, ele não realmente explicar alguns dos sites terríveis que eu vi que nunca parecem carregamento de chegada ...
John O
2
John O, eu já vi algumas implementações do SCARY JSON no meu tempo, envolvendo matrizes 2D / 3D, incluindo códigos IATA (aeroporto), códigos IATA (aeroporto), companhias aéreas, companhias aéreas, operadores turísticos, resorts, etc. em uma matriz. É ... ... 1MB + downloads JSON me fazem querer chorar.
Norguard 17/07/12
4
var array = [ 1, 2, 3, 4];

é açúcar

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

é sal

ceder
fonte
5
e onde usá-lo, para café ou macarrão?
Aristos
açúcar e sal sintáticos
linquize
3

É porque new Array()é ambíguo. Estes são os construtores corretos:

// 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
fonte