В чем реальная разница между объявлением массива следующим образом:
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