¿Cuáles son las mejores prácticas a seguir al declarar una matriz en Javascript?

176

Cuando necesito declarar una nueva matriz, uso esta notación

var arr = new Array();

Pero cuando realizo pruebas en línea, por ejemplo en jsbin , una advertencia me indica "Usar la notación literal de matriz []".

No encontré una razón para evitar usar el constructor. ¿Es de alguna manera menos eficiente que usar []? ¿O es una mala práctica?

¿Hay una buena razón para usar en var arr = [];lugar de var arr = new Array();?

Naigel
fuente
55
Ambos estan bien. Simplemente guarda algunos bytes en la transmisión.
Sirko
13
De hecho, hay diferencias. Ver esta publicación: stackoverflow.com/q/2280285/921204
techfoobar
Nota: existen diferencias si Array solo se ha sobrescrito .
crdx
@apkd en algunos navegadores hay una diferencia de rendimiento significativa
Alnitak
Lo suficientemente justo. No vi eso en la pregunta vinculada.
crdx

Respuestas:

260

En su mayoría , la gente usa var a = []porque Douglas Crockford lo dice .

Sus razones incluyen el comportamiento no 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

Tenga en cuenta que no hay forma new Array()de crear una matriz con solo un elemento de número preespecificado.

¡El uso []es en realidad más eficiente y más seguro también ! Es posible sobrescribir el Arrayconstructor y hacer que haga cosas extrañas, pero no puede sobrescribir el comportamiento de [].

Personalmente, siempre uso la []sintaxis, y de manera similar siempre uso la {}sintaxis en lugar de new Object().

Alnitak
fuente
55
"no se puede sobrescribir el comportamiento de []". ¿Estas seguro acerca de esto? Pensé que podría sobrescribir el constructor Array para afectar [], y el constructor Object para afectar {}, al menos en algunas implementaciones.
Random832
11
@ Random832 tal vez en navegadores más antiguos, pero no en implementaciones compatibles con ES5, donde la especificación dice que []llama a un constructor interno, no el valor Array.constructorque tenga en ese momento.
Alnitak
55
Bonificación: los literales de matriz son mucho más rápidos que crear nuevas matrices utilizando el Arrayconstructor: jsperf.com/new-array
Mathias Bynens
@MathiasBynens solo a veces.
OrangeDog
Ew @ the [] funciona de manera diferente debido al constructor interno. La inconsistencia causará más confusión de la que ahorra. Editar: Ah, preocupación de seguridad. Lo entiendo.
Erik Reppen
48

Una diferencia significativa es que siempre[] creará una nueva matriz, mientras que podría ser secuestrada para crear un objeto diferente .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 = [];
}());​

En mi código de ejemplo, he mantenido la Arrayfunción oculta del resto del alcance del documento, sin embargo, es más probable que si alguna vez te encuentras con este tipo de problema, el código no se haya dejado en un buen cierre, y lo hará probablemente sea difícil de localizar.

Descargo de responsabilidad : no es una buena idea secuestrar al Arrayconstructor.

zzzzBov
fuente
77
IIRC, en los navegadores más antiguos que anulan el constructor Array también causaría que los literales se interpreten incorrectamente. Hubo una vulnerabilidad de GMail CSRF hace un tiempo, los involucrados anulan el constructor de matrices y los nuevos navegadores ignoran la sobrecarga de literales por esta razón precisa.
hugomg
Contra-descargo de responsabilidad: sin embargo, ha sido extremadamente útil y útil para mejorar el constructor de Array a lo largo de los años.
Erik Reppen
26

para mantenimiento, use []

El literal de matriz es más predecible, ya que la mayoría de los desarrolladores lo usan. La mayor parte del uso de la matriz usará el literal, y es valioso que su código coincida con lo que usan otros desarrolladores.

para matrices vacías, use []

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

Como se muestra aquí , usar el literal para vacío y un par de elementos conocidos es más gordo que el constructor Array.

para una matriz de tamaño conocido, use new Array(size)

Si se conoce el tamaño, el uso del constructor Array mejora significativamente el rendimiento. Sin embargo, también significa que tiene que lidiar con una matriz que ya tiene 'indefinido' llenando todos sus valores.

Como se muestra aquí

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

Esto también funciona para matrices muy pequeñas también .

JL235
fuente
12

No, en realidad no hay ninguna razón para usar una notación sobre la otra para matrices vacías.

Sin embargo, la mayoría de los navegadores muestran un rendimiento ligeramente mejor usando x = [];que llamando al Constructor .

Si necesita crear una matriz con un tamaño específico, necesita usar, x = new Array(10);por ejemplo, lo que crearía una matriz con 10 undefinedranuras.

jAndy
fuente
@Alnitak: que ya mencionaste, no es muy intuitivo y conciso.
jAndy
77
Creé un jsperf para comparar el rendimiento: jsperf.com/array-constructor-versus-literal . Al menos para mí en Chrome 20 en Ubuntu, el literal es dos veces más rápido que el constructor.
Steven
jAndy, ¿por qué quieres una matriz con "10 espacios vacíos" en JavaScript? En realidad, puede hacer exactamente lo mismo con: var arr = []; arr [9] = "omega"; 1. Las matrices en JS son totalmente dinámicas, puede hacer referencia a cualquier índice que desee y simplemente será "indefinido". Esto es tan cierto como si fuera a decir: var arr = new Array (10); arr [23]; 2. la longitud de la matriz se establecerá en el valor más alto que tenga algo, independientemente de cuántas ranuras no definidas haya entre ellas. O puedes configurarlo tú mismo. [] podría no curar el cáncer, pero es marginalmente mejor.
Norguard
7
  • var arr = [] usa la matriz / objeto literal
  • var arr = new Array () usa el constructor array / object

La forma más rápida de definir una matriz u objeto es literal, porque no es necesario llamar al constructor

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
fuente
2
Como referencia, detrás de escena, var arr = [];lógicamente también usa un constructor. Simplemente siempre es el constructor de matriz incorporado, en lugar de cualquier función que actualmente tenga el nombre Array.
cHao
6

Ambos son correctos solamente. Pero la mayoría de la gente usavar a = []

Tres formas de declarar una matriz en JavaScript.

Método 1 : podemos declarar explícitamente una matriz con la palabra clave "nueva" de JavaScript para crear una instancia de la matriz en la memoria (es decir, crearla y ponerla a disposición).

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

Método 2 : utilizamos un método alternativo para declarar matrices.

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

Método 3 : JavaScript también le permite crear matrices indirectamente, llamando a métodos específicos.

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

Hay un límite que el constructor puede tomar como argumentos.

En la mayoría de los sistemas, el límite es 2 ^ 16 (2 bytes):

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

Eso causará un error (demasiados argumentos ...)

Al usar el literal [] no tienes tales problemas.

En caso de que no te interesen esos arreglos tan grandes, creo que puedes usar lo que prefieras.

Erwin Moller
fuente
2
¿Puedes citar un ejemplo de dónde una persona podría razonablemente querer crear una matriz previamente poblada con 70,000 valores? Sin embargo, realmente explica algunos de los sitios web horribles que he visto que nunca parecen terminar de cargar ...
John O
2
John O, he visto algunas implementaciones de SCARY JSON en mi tiempo, que involucran matrices de matrices 2D / 3D, con códigos IATA (aeropuerto), compañías aéreas, operadores turísticos, resorts, etc. ... todo relleno en una matriz Es ... ... 1MB + Las descargas JSON me dan ganas de llorar.
Norguard
4
var array = [ 1, 2, 3, 4];

es azucar

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

es sal

linquizar
fuente
55
¿Y dónde usarlo, para café o para pasta?
Aristos
azúcar y sal sintácticos
linquize
3

Es porque new Array()es ambiguo. Estos son los constructores correctos:

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