Каковы лучшие практики, которым нужно следовать при объявлении массива в Javascript?

176

Когда мне нужно объявить новый массив, я использую эту запись

var arr = new Array();

Но при тестировании в Интернете, например, на jsbin , появляется предупреждение «Использовать буквенное обозначение массива []».

Я не нашел причины избегать использования конструктора. В каком-то смысле менее эффективно, чем использовать []? Или это плохая практика?

Есть ли веская причина для использования var arr = [];вместо var arr = new Array();?

Naigel
источник
5
Оба в порядке. Вы просто сохраняете несколько байтов при передаче.
Сирко
13
Различия действительно есть. Смотрите это сообщение: stackoverflow.com/q/2280285/921204
techfoobar
Примечание: есть различия, если массив был перезаписан только.
crdx
@apkd в некоторых браузерах есть существенная разница в производительности
Alnitak
Справедливо. Я не видел этого в связанном вопросе.
crdx

Ответы:

260

В основном люди используют, var a = []потому что так говорит Дуглас Крокфорд .

Его причины включают не интуитивное и противоречивое поведение 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

Обратите внимание, что невозможно new Array()создать массив с одним предварительно заданным числовым элементом!

Использование []на самом деле более эффективно и безопасно ! Можно переписать Arrayконструктор и заставить его делать странные вещи, но вы не можете переписать поведение [].

Лично я всегда использую []синтаксис и аналогично всегда использую {}синтаксис вместо new Object().

Альнитак
источник
5
«Вы не можете переписать поведение [].» вы уверены в этом? Я думал, что вы можете переписать конструктор Array, чтобы повлиять на [], и конструктор Object, чтобы повлиять на {}, по крайней мере, в некоторых реализациях.
Random832
11
@ Random832 может быть в более старых браузерах, но не в ES5-совместимых реализациях, где спецификация говорит, что []вызывает внутренний конструктор, а не какое-либо значение Array.constructor, полученное в то время.
Альнитак
5
Бонус: литералы массивов намного быстрее, чем создание новых массивов с помощью Arrayконструктора: jsperf.com/new-array
Матиас
@MathiasBynens только иногда.
OrangeDog
Ew @ the [] работает по-другому из-за внутреннего конструктора. Несоответствие вызовет больше путаницы, чем спасет. Изменить: Ах, проблема безопасности. Я понял
Эрик Реппен
48

Одно существенное отличие состоит в том, []что всегда будет создаваться экземпляр нового массива, тогда как он 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 = [];
}());​

В моем примере кода я сохранил Arrayфункцию скрытой от остальной области документа, однако, более вероятно, что если вы когда-нибудь столкнетесь с такой проблемой, код не останется в хорошем закрытии и будет вероятно, будет трудно найти.

Отказ от ответственности : это не очень хорошая идея, чтобы захватить Arrayконструктор.

zzzzBov
источник
7
IIRC, в старых браузерах, перекрывающих конструктор Array, также приводил к неверной интерпретации литералов. Некоторое время назад была уязвимость GMail CSRF, связанная с переопределением конструктора массива, и новые браузеры игнорируют перегрузку для литералов по этой точной причине.
hugomg
Встречный отказ от ответственности: однако он был чрезвычайно полезным и полезным для улучшения конструктора Array на протяжении многих лет.
Эрик Реппен
26

для удобства использования используйте []

Литерал массива более предсказуем, поскольку большинство разработчиков используют его. Большая часть использования массива будет использовать литерал, и есть смысл в том, чтобы ваш код соответствовал тому, что используют другие разработчики.

для пустых массивов используйте []

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

Как показано здесь , использование литерала для пустых и пары известных элементов намного проще, чем конструктор Array.

для массива известного размера используйте new Array(size)

Если размер известен, то использование конструктора Array значительно повышает производительность. Однако это также означает, что вам приходится иметь дело с массивом, который уже имеет неопределенное значение, заполняющее все его значения.

Как показано здесь

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

Это также работает для очень маленьких массивов .

JL235
источник
12

Нет, на самом деле нет причин использовать одну нотацию над другой для пустых массивов.

Тем не менее, большинство браузеров показывают немного лучшую производительность , используя , x = [];чем вызов конструктора .

Если вам нужно создать массив с определенным размером, вам, например, нужно использовать x = new Array(10);массив, который бы создал массив с 10 undefinedслотами.

JANDY
источник
@Alnitak: который вы уже упоминали, не очень интуитивно понятен и лаконичен.
Джэнди
7
Я собрал jsperf для сравнения производительности: jsperf.com/array-constructor-versus-literal . По крайней мере, для меня на Chrome 20 на Ubuntu, литерал в два раза быстрее конструктора.
Стивен
jAndy, зачем вам массив с «10 пустыми слотами» в JavaScript? В действительности вы можете сделать то же самое с: var arr = []; arr [9] = "омега"; 1. Массивы в JS являются полностью динамическими, вы можете ссылаться на любой индекс, который вам нужен, и он будет просто «неопределен». Это так же верно, как если бы вы сказали: var arr = new Array (10); обр [23]; 2. Длина массива будет установлена ​​на самое высокое значение, в котором есть что-либо, независимо от того, сколько неопределенных слотов находится между ними. Или вы можете установить его самостоятельно. [] не может вылечить рак, но это немного лучше.
Норгард
7
  • var arr = [] использует массив / объектный литерал
  • var arr = new Array () использовать конструктор массива / объекта

Самый быстрый способ определить массив или объект - буквальный, потому что вам не нужно вызывать конструктор

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
Ясир Махмуд
источник
2
Для справки, за кулисами, var arr = [];логически также используется конструктор. Это просто всегда встроенный конструктор массива, а не какая-либо функция, которая в данный момент работает по имени Array.
Чао
6

Оба верны только. Но большинство людей используютvar a = []

Три способа объявить массив в JavaScript.

Метод 1 : Мы можем явно объявить массив с ключевым словом JavaScript «new», чтобы создать экземпляр массива в памяти (т.е. создать его и сделать его доступным).

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

Метод 2 : мы используем альтернативный метод для объявления массивов.

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

Метод 3 : JavaScript также позволяет создавать массивы косвенно, вызывая определенные методы.

// Create an array from a method's return value
var carter = "I-learn-JavaScript";
var arlene3 = carter.split("-");
RAN
источник
4

Существует ограничение, которое конструктор может принимать в качестве аргументов.

В большинстве систем я допустил ограничение 2 ^ 16 (2 байта):

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

Это приведет к ошибке (слишком много аргументов ....)

При использовании буквального [] у вас нет таких проблем.

Если вам не нужны такие большие массивы, я думаю, вы можете использовать все, что пожелаете.

Эрвин Моллер
источник
2
Можете ли вы привести пример, когда человек разумно хотел бы создать массив, предварительно заполненный 70000 значений? Тем не менее, это действительно объясняет некоторые ужасные веб-сайты, которые я видел, которые, кажется, никогда не заканчивают загружаться ...
Джон О
2
Джон О, в свое время я видел несколько реализаций SCARY JSON, включающих в себя массивы 2D / 3D-массивов с кодами IATA (аэропорт), авиакомпании, туроператоры, курорты и так далее ... ... все наполнено в один массив. Это ... ... загрузка 1MB + JSON заставляет меня плакать.
Норгард
4
var array = [ 1, 2, 3, 4];

это сахар

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

это соль

linquize
источник
5
и где его использовать, для кофе или для макарон?
Аристос
синтаксический сахар и соль
linquize
3

Это потому, что new Array()это неоднозначно. Это правильные конструкторы:

// 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)
Флоран
источник