В чем реальная разница между объявлением массива следующим образом:
var myArray = new Array();
а также
var myArray = [];
В чем реальная разница между объявлением массива следующим образом:
var myArray = new Array();
а также
var myArray = [];
Ответы:
Разница есть, но в этом примере нет разницы.
Использование более подробного метода: new Array()имеет один дополнительный параметр в параметрах: если вы передадите число конструктору, вы получите массив такой длины:
x = new Array(5);
alert(x.length); // 5
Чтобы проиллюстрировать различные способы создания массива:
var a = [], // these are the same
b = new Array(), // a and b are arrays with length 0
c = ['foo', 'bar'], // these are the same
d = new Array('foo', 'bar'), // c and d are arrays with 2 strings
// these are different:
e = [3] // e.length == 1, e[0] == 3
f = new Array(3), // f.length == 3, f[0] == undefined
;
Другое отличие состоит в том, что при использовании new Array()вы можете установить размер массива, который влияет на размер стека. Это может быть полезно, если вы получаете переполнение стека ( Performance of Array.push vs Array.unshift ), что происходит, когда размер массива превышает размер стека, и его необходимо создать заново. Таким образом, на самом деле, в зависимости от варианта использования, может быть увеличение производительности при использовании, new Array()потому что вы можете предотвратить переполнение.
Как указано в этом ответе , на new Array(5)самом деле не будет добавлять пять undefinedэлементов в массив. Это просто добавляет место для пяти предметов. Помните, что использование Arrayэтого способа затрудняет использование array.lengthрасчетов.
Разница между созданием массива с неявным массивом и конструктором массива невелика, но важна.
Когда вы создаете массив с помощью
var a = [];
Вы говорите интерпретатору создать новый массив времени выполнения. Никакой дополнительной обработки не требуется вообще. Выполнено.
Если вы используете:
var a = new Array();
Вы говорите интерпретатору, я хочу вызвать конструктор " Array" и сгенерировать объект. Затем он просматривает ваш контекст выполнения, чтобы найти конструктор для вызова, и вызывает его, создавая ваш массив.
Вы можете подумать: «Ну, это совсем не важно. Они одинаковые!». К сожалению, вы не можете гарантировать это.
Возьмите следующий пример:
function Array() {
this.is = 'SPARTA';
}
var a = new Array();
var b = [];
alert(a.is); // => 'SPARTA'
alert(b.is); // => undefined
a.push('Woa'); // => TypeError: a.push is not a function
b.push('Woa'); // => 1 (OK)
В приведенном выше примере, первый звонок предупредит 'SPARTA', как и следовало ожидать. Второго не будет. В итоге вы увидите неопределенное. Вы также заметите, что b содержит все встроенные функции объекта Array, такие как push, а другие нет.
Хотя вы можете ожидать, что это произойдет, это просто иллюстрирует тот факт, что []это не то же самое, что new Array().
Лучше всего просто использовать, []если вы знаете, что хотите просто массив. Я также не предлагаю идти вокруг и переопределять Массив ...
Есть важное отличие, о котором пока не упоминается ни один ответ.
Из этого:
new Array(2).length // 2
new Array(2)[0] === undefined // true
new Array(2)[1] === undefined // true
Вы можете подумать, что new Array(2)это эквивалентно [undefined, undefined], но это не так!
Давайте попробуем с map():
[undefined, undefined].map(e => 1) // [1, 1]
new Array(2).map(e => 1) // "(2) [undefined × 2]" in Chrome
Видеть? Семантика совершенно другая! Так почему это так?
Согласно ES6 Spec 22.1.1.2, работа Array(len)заключается в создании нового массива, свойство lengthкоторого установлено в качестве аргумента, lenи это все, что означает, что внутри этого вновь созданного массива нет никаких реальных элементов .
Функция в map()соответствии со спецификацией 22.1.3.15 сначала проверяет, а HasPropertyзатем вызывает обратный вызов, но получается, что:
new Array(2).hasOwnProperty(0) // false
[undefined, undefined].hasOwnProperty(0) // true
И поэтому вы не можете ожидать, что итеративные функции будут работать как обычно с массивами, созданными изnew Array(len) .
Кстати, Safari и Firefox гораздо лучше «печатают» эту ситуацию:
// Safari
new Array(2) // [](2)
new Array(2).map(e => 1) // [](2)
[undefined, undefined] // [undefined, undefined] (2)
// Firefox
new Array(2) // Array [ <2 empty slots> ]
new Array(2).map(e => 1) // Array [ <2 empty slots> ]
[undefined, undefined] // Array [ undefined, undefined ]
Я уже отправил вопрос в Chromium и попросил их исправить эту запутанную печать: https://bugs.chromium.org/p/chromium/issues/detail?id=732021
ОБНОВЛЕНИЕ: Это уже исправлено. Chrome теперь печатается как:
new Array(2) // (2) [empty × 2]
[...Array(2)]которая эквивалентна [undefined, undefined]с точки зрения результатов.
undefinedкак обычно.
Как ни странно, new Array(size)это почти в 2 раза быстрее, чем []в Chrome, и примерно столько же в FF и IE (измеряется путем создания и заполнения массива). Это имеет значение, только если вы знаете приблизительный размер массива. Если вы добавите больше элементов, чем указали длину, повышение производительности будет потеряно.
Точнее: Array(быстрая операция с постоянным временем, которая не выделяет память, тогда []как операция с линейным временем, которая устанавливает тип и значение.
new Array(length)на 0 <= размер <= ~ 1000, на размер> ~ 1000 побед[]
Для получения дополнительной информации на следующей странице описано, почему вам никогда не нужно использоватьnew Array()
Вам никогда не нужно использовать
new Object()в JavaScript.{}Вместо этого используйте литерал объекта . Точно так же не используйтеnew Array(),[]вместо этого используйте литерал массива . Массивы в JavaScript не работают так же, как массивы в Java, и использование Java-подобного синтаксиса вас смущает.Не используйте
new Number,new Stringилиnew Boolean. Эти формы создают ненужные обертки объектов. Просто используйте простые литералы вместо этого.
Также ознакомьтесь с комментариями - new Array(length)форма не служит какой-либо полезной цели (по крайней мере, в сегодняшних реализациях JavaScript).
Для того, чтобы лучше понять []и new Array():
> []
[]
> new Array()
[]
> [] == []
false
> [] === []
false
> new Array() == new Array()
false
> new Array() === new Array()
false
> typeof ([])
"object"
> typeof (new Array())
"object"
> [] === new Array()
false
> [] == new Array()
false
Вышеуказанный результат получен из консоли Google Chrome в Windows 7.
Array(3)или new Array(3)не такие, как [3].
Первый - это вызов конструктора объекта по умолчанию. Вы можете использовать его параметры, если хотите.
var array = new Array(5); //initialize with default length 5
Второй дает вам возможность создавать не пустой массив:
var array = [1, 2, 3]; // this array will contain numbers 1, 2, 3.
var array = [5]использовать квадратные скобки, но не использовать конструктор, так как var array = Array(5)создает пустой массив из 5 элементов.
Я могу объяснить более конкретно, начиная с этого примера, основанного на хорошем примере Фредрика.
var test1 = [];
test1.push("value");
test1.push("value2");
var test2 = new Array();
test2.push("value");
test2.push("value2");
alert(test1);
alert(test2);
alert(test1 == test2);
alert(test1.value == test2.value);
Я просто добавил еще одно значение в массивы и сделал четыре предупреждения: первое и второе - дать нам значение, хранящееся в каждом массиве, чтобы быть уверенным в значениях. Они вернутся так же! Теперь попробуйте третий, он возвращает ложь, потому что
JS рассматривает test1 как переменную с типом данных массива , и он рассматривает test2 как объект с функциональностью массива , и здесь есть несколько небольших различий.
Первое отличие в том, что когда мы вызываем test1, он вызывает переменную, не задумываясь, он просто возвращает значения, которые хранятся в этой переменной, независимо от ее типа данных! Но, когда мы называем test2 он вызывает Array () функцию , а затем он хранит наши «Толкаемые» значения в «Значение» собственности, и то же самое происходит , когда мы начеку test2, он возвращает «Value» свойство объекта массива.
Поэтому, когда мы проверяем, равно ли test1 равен test2, они, конечно, никогда не вернут true, один - функция, а другой - переменная (с типом массива), даже если они имеют одинаковое значение!
Чтобы быть уверенным в этом, попробуйте 4-е предупреждение с добавлением .value; это вернет истину. В этом случае мы сообщаем JS «Независимо от типа контейнера, будь то функция или переменная, сравните значения, хранящиеся в каждом контейнере, и скажите нам, что вы видели!» именно так и происходит.
Надеюсь, я четко сформулировал эту идею, и извините за мой плохой английский.
[]и new Array()идентичен; .valueбудет undefinedв обоих случаях, и сравнение их всегда будет ложным.
array.value. и то и другое typeof []и typeof new Array()вернуть object. Это одна из причин, почему существует функция с именемArray.isArray
Нет разницы, когда вы инициализируете массив без какой-либо длины. Так var a = []и var b = new Array()есть то же самое.
Но если вы инициализируете массив с такой же длиной var b = new Array(1);, он установит длину объекта массива равной 1. Так что это эквивалентно var b = []; b.length=1;.
Это будет проблематично всякий раз, когда вы делаете array_object.push, он добавляет элемент после последнего элемента и увеличивает длину.
var b = new Array(1);
b.push("hello world");
console.log(b.length); // print 2
против
var v = [];
a.push("hello world");
console.log(b.length); // print 1
Первый - это конструктор объекта по умолчанию call.most, используемый для динамических значений.
var array = new Array(length); //initialize with default length
второй массив используется при создании статических значений
var array = [red, green, blue, yellow, white]; // this array will contain values.
Большой разницы нет, они в основном делают одно и то же, но делают это по-разному, но читайте дальше, посмотрите на это утверждение на W3C:
var cars = ["Saab", "Volvo","BMW"];
а также
var cars = new Array("Saab", "Volvo", "BMW");
Два приведенных выше примера делают то же самое. Нет необходимости использовать новый Array ().
Для простоты, читабельности и скорости выполнения используйте первый (метод литерала массива).
Но в то же время создание нового массива с использованием new Arrayсинтаксиса считается плохой практикой:
Избегайте нового массива ()
Нет необходимости использовать встроенный в JavaScript конструктор массива new Array ().
Вместо этого используйте [].
Эти два разных оператора создают новый пустой массив с именем points:
var points = new Array(); // Bad
var points = []; // Good
Эти два разных оператора создают новый массив, содержащий 6 чисел:
var points = new Array(40, 100, 1, 5, 25, 10); // Bad
var points = [40, 100, 1, 5, 25, 10]; // Good
Новое ключевое слово только усложняет код. Это также может привести к неожиданным результатам:
var points = new Array(40, 100); // Creates an array with two elements (40 and 100)
Что если я удалю один из элементов?
var points = new Array(40); // Creates an array with 40 undefined elements !!!!!
Таким образом, в принципе не считается лучшей практикой, также есть одно небольшое отличие, вы можете передать длину, new Array(length)как это, что также не рекомендуется.
new Array(40).fill(123)
Разница в использовании
var arr = new Array(size);
Или
arr = [];
arr.length = size;
Как достаточно обсуждалось в этом вопросе.
Я хотел бы добавить вопрос скорости - текущий быстрый путь, на google chromeвторой один.
Но обратите внимание, эти вещи, как правило, сильно меняются с обновлениями. Также время выполнения будет отличаться в разных браузерах.
Например, второй вариант, который я упомянул, работает со скоростью 2 миллиона [операций в секунду] chrome, но если вы попробуете его, mozilla dev.вы получите удивительно более высокий показатель - 23 миллиона.
В любом случае, я бы посоветовал вам проверять это время от времени на разных браузерах (и машинах), используя сайт как таковой.
Как я знаю, различие вы можете найти срез (или другие функции массива), такие как code1. И code2 показывают u Array и его экземпляры :
code1:
[].slice; // find slice here
var arr = new Array();
arr.slice // find slice here
Array.prototype.slice // find slice here
code2:
[].__proto__ == Array.prototype; // true
var arr = new Array();
arr.__proto__ == Array.prototype; // true
вывод:
как вы можете видеть []и new Array()создавать новый экземпляр Array. И все они получают функции прототипа изArray.prototype
Они просто разные экземпляры Array.so это объясняет, почему
[] != []
:)
Я столкнулся со странным поведением, используя [].
У нас есть «классы» модели с полями, инициализированными до некоторого значения. Например:
require([
"dojo/_base/declare",
"dijit/_WidgetBase",
], function(declare, parser, ready, _WidgetBase){
declare("MyWidget", [_WidgetBase], {
field1: [],
field2: "",
function1: function(),
function2: function()
});
});
Я обнаружил, что когда поля инициализируются, []тогда они будут общими для всех объектов модели. Внесение изменений в один влияет на всех остальных.
Этого не происходит, инициализируя их new Array(). То же самое для инициализации объектов ( {}против новых Object())
TBH Я не уверен, если это проблема с фреймворком, который мы использовали ( Dojo )
Это больше, чем кажется на первый взгляд. Большинство других ответов верны, НО ТАКЖЕ ..
new Array(n)nэлементов[1, 2, 3] || []deleteили [1,,3]синтаксис)for .., forEach, mapи т.д.)Это, вероятно , не относится к более старым версиям / браузерам.
Я обнаружил одно различие между двумя конструкциями, которое меня сильно укусило.
Допустим, у меня есть:
function MyClass(){
this.property1=[];
this.property2=new Array();
};
var MyObject1=new MyClass();
var MyObject2=new MyClass();
В реальной жизни, если я делаю это:
MyObject1.property1.push('a');
MyObject1.property2.push('b');
MyObject2.property1.push('c');
MyObject2.property2.push('d');
В итоге я получаю вот что:
MyObject1.property1=['a','c']
MyObject1.property2=['b']
MyObject2.property1=['a','c']
MyObject2.property2=['d']
Я не знаю, что должно произойти в спецификации языка, но если я хочу, чтобы мои два объекта имели уникальные массивы свойств в моих объектах, я должен использовать new Array().
[]и new Array()конструктор, что приводит к одному элементу на массив на свойство. В вашем коде должно быть что-то еще, чтобы в итоге вы получили результат, показанный выше.
var property1static=[]; function MyClass(){ this.property1=property1static; this.property2=new Array(); };
Использование конструктора Array создает новый массив требуемой длины и заполняет каждый из индексов неопределенным, назначенный массив переменной создает индексы, для которых вы предоставляете ему информацию.
[]лексем:ARRAY_INIT;new Arrayжетоны:NEW, IDENTIFIER;new Array()жетоны:NEW, IDENTIFIER, CALL