Які найкращі практики слід дотримуватися при оголошенні масиву в Javascript?


176

Коли мені потрібно оголосити новий масив, я використовую це позначення

var arr = new Array();

Але під час тестування в Інтернеті, наприклад, на jsbin , попередження сигналізує мені про "Використовувати буквене позначення масиву []."

Я не знайшов причин уникати використання конструктора. Це в чомусь менш ефективно, ніж використання []? Або це погана практика?

Чи є вагомі причини використовувати var arr = [];замість цього var arr = new Array();?


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 вплинути на {}, принаймні на деякі реалізації.
Випадково832

11
@ Random832, можливо, у старих браузерах, але не в ES5-сумісних реалізаціях, де специфікація говорить про те, що []викликає внутрішній конструктор, не залежно від того , яке значення Array.constructorмає на той час.
Альнітак

5
Бонус: Літерали масиву набагато швидше, ніж створення нових масивів за допомогою Arrayконструктора: jsperf.com/new-array
Mathias Bynens

@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конструктор.


7
IIRC, у старих браузерах, що переосмислюють конструктор Array, також буде спричинено неправильне тлумачення літералів. Нещодавно виникла вразливість GMail CSRF, яка займалася перекриттям конструктора масиву, а нові браузери ігнорували перевантаження для літералів саме з цієї точної причини.
hugomg

Контрвідмова від відповідальності: однак вона надзвичайно корисна і корисна для вдосконалення конструктора масиву протягом багатьох років.
Ерік Реппен

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;
}

Це також працює і для дуже малих масивів .


12

Ні, насправді немає причин використовувати одне позначення над іншим для порожніх масивів.

Однак більшість браузерів демонструє дещо кращу ефективність, x = [];ніж виклик конструктора .

Якщо вам потрібно створити масив із певним розміром, вам потрібно використовувати, x = new Array(10);наприклад, який створив би масив з 10 undefinedслотами.


@Alnitak: про який ви вже згадували, не дуже інтуїтивно та стисло.
jAndy

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); arr [23]; 2. Для довжини масиву буде встановлено найвище значення, що має щось у ньому, незалежно від кількості невизначених слотів між ними. Або ви можете встановити його самостійно. [] може не вилікувати рак, але це незначно краще.
Норгуард

7
  • var arr = [] використовує масив / об'єкт літерал
  • var arr = новий масив () використовувати конструктор масиву / об'єкта

Найшвидший спосіб визначити масив або об’єкт - це буквальний шлях, тому що вам не потрібно викликати конструктор

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.
cHao

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("-");

4

Існує обмеження, яке конструктор може взяти за аргументи.

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

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

Це призведе до помилки (занадто багато аргументів ....)

Під час використання literal [] у вас немає таких проблем.

Якщо вам не байдужі такі великі масиви, я думаю, ви можете використовувати все, що завгодно.


2
Чи можете ви навести приклад того, коли людина може розумно захотіти створити масив, попередньо заповнений зі значеннями 70 000? Хоча це дійсно пояснює деякі жахливі веб-сайти, які я бачив, і ніколи не закінчується завантаженням ...
Джон О

2
Джон О, я свого часу бачив кілька реалізацій СКАРІ JSON, що включають масиви 2D / 3D-масивів, що містять коди IATA (аеропорт), компанії авіакомпаній, туроператорів, курортів та інше ... ... в один масив. Це ... ... завантаження 1 Мб + JSON змушує мене плакати.
Норгуард


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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.