JavaScript 배열을 선언하는 동안 "Array ()"와 "[]"의 차이점은 무엇입니까?


841

다음과 같이 배열을 선언하는 것의 실제 차이점은 무엇입니까?

var myArray = new Array();

var myArray = [];

[]토큰 : ARRAY_INIT; new Array토큰 : NEW, IDENTIFIER; new Array()토큰 :NEW, IDENTIFIER, CALL
noobninja

답변:


951

차이는 있지만이 예에서는 차이가 없습니다.

더 자세한 방법을 사용하면 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()배열의 크기를 설정할 수 있으며 이는 스택 크기에 영향을 미칩니다. 이것은 배열의 크기가 스택의 크기를 초과하여 다시 만들어야 할 때 발생하는 스택 오버플로 ( Array.push vs Array.unshift의 성능)를 얻는 경우 유용 할 수 있습니다 . 따라서 실제로 사용 사례에 따라 new Array()오버플로가 발생하는 것을 방지 할 수 있으므로 사용시 성능이 향상 될 수 있습니다.

에서 지적 이 답변 , new Array(5)실제로 다섯 개 추가하지 않습니다 undefined배열에 항목을. 단순히 5 개의 항목을위한 공간을 추가합니다. Array이 방법 을 사용 하면 array.length계산 에 의존하기가 어렵습니다 .


66
이것은 약간 잘못되었습니다. new Array ()와 [] 사이에는 매우 중요한 차이점이 하나 있습니다. 제 대답을 자세히 설명하겠습니다.
코더

30
그러나 귀하의 답변에서 언급했듯이 완전히 미쳤고 Array 함수를 덮어 쓰는 경우에만 다릅니다.
별자리

19
중요한 것은 new 연산자를 사용하면 인터프리터가 모든 범위의 추가 단계를 수행하여 전역 범위로 이동하고 생성자를 찾고 생성자를 호출하고 결과를 할당한다는 것입니다. 대부분의 경우 런타임 배열. [] 만 사용하면 전역 생성자를 찾는 오버 헤드를 피할 수 있습니다. 작게 보일지 모르지만 앱에서 거의 실시간 성능을 위해 촬영할 때 차이가 생길 수 있습니다.
coderjoe

5
큰 성능 차이가 있습니다 : jsperf.com/create-an-array-of-initial-size/2/2
Marco Luglio

4
물론 세미콜론이나 줄 바꿈도 추가하지 않아도됩니다. 일관성과 가독성에 관한 것입니다. 당신은 알고 있습니다.
nickf

774

암시 적 배열을 사용한 배열 작성과 배열 생성자의 차이점은 미묘하지만 중요합니다.

를 사용하여 배열을 만들 때

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에는 다음과 같은 기본 배열 객체 함수가 모두 포함되어 있습니다.push .

이 일 것으로 예상 할 수 있지만, 그것은 단지 사실 설명 []과 동일하지 않습니다를new Array() .

[]배열을 원한다는 것을 알고 있다면 사용 하는 것이 가장 좋습니다 . 또한 배열을 둘러보고 재정의하는 것이 좋습니다.


157
내가 생각하기에 어떤 종류의 사람이 배열 클래스를 덮어 쓸 것인지, 나는 모른다 ...
nickf

160
당신 말이 맞아요 madman만이 배열 클래스를 덮어 씁니다. 이제 잠시 시간을내어 new Array ()를 사용하여 모든 추가 작업을 고려하여 통역사가 이러한 미친 사람들을 지원하도록하십시오. 난 그냥 []와 함께 모두 피하십시오.
coderjoe

51
JavaScript로 가능한 글로벌 오염의 좋은 예입니다.
David Snabel-Caunt

8
새로운 Array (size)는 [] 표기법을 사용하는 다른 가능한 방법보다 빠릅니다. 출처 : jsperf.com/create-an-array-of-initial-size/2/2
Marco Luglio

9
불행히도 그 테스트는 부적절하게 준비되었습니다. 배열의 초기화와 배열 액세스로 배열의 초기화를 테스트하고 있습니다. 브라우저가 실제로 메모리를 사전 할당하고 있음을 증명할 수있는 제어 기능이 없습니다 (사양에서는 반드시 그렇지 않아야 함). 배열 액세스가 일정하고 대부분의 시간이 두 예제 모두에서 메모리를 할당하는 데 소비된다고 가정 할 수 있다면 수백만 개의 배열을 인스턴스화하는 경우 []가 바람직 할 수 있습니다. jsperf.com/array-instanciation
coderjoe

95

아직 답변이없는 중요한 차이점이 있습니다.

이것으로부터:

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

BTW, 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]

22
너의 유일한 대답이다
Victor

이것은 의미가 있습니다. 저는 문서화 된 참조를 찾을 수없는 다른 구조에 부딪 쳤습니다 . 결과 관점 [...Array(2)]과 동일합니다 [undefined, undefined].
Roberto Andrade

내 이전 의견에 대한 답변은 "확산 연산자"입니다. javascript.info/rest-parameters-spread-operator
Roberto Andrade

스프레드 연산자는 항목을 읽어야하므로 복사를 적용 undefined하고 평소 와 같이 빈 슬롯 반환 을 읽을 수 있기 때문에 @RobertoAndrade가 의미가 있습니다 .
Hux

51

이상하게도 new Array(size)거의 2 배 빠릅니다.[] Chrome FF 및 IE (배열 생성 및 채우기로 측정)와 거의 동일합니다. 배열의 대략적인 크기를 아는 경우에만 중요합니다. 주어진 길이보다 많은 항목을 추가하면 성능 향상이 손실됩니다.

더 정확하게 : Array(메모리를 할당하지 않는 빠른 상수 시간 연산이며, []유형과 값을 설정하는 선형 시간 연산입니다.


3
Node.js에서 많이 테스트했습니다. 배열 new Array(length)에 0 <= size <= ~ 1000, size> ~ 1000 wins에 일정량의 항목을 넣어야 할 때[]
glukki


40

자세한 내용 은 다음 페이지에서 왜 사용할 필요가 없는지 설명합니다new Array()

new Object()JavaScript 에서는 사용할 필요가 없습니다 . {} 대신 객체 리터럴을 사용하십시오 . 마찬가지로을 사용하지 말고 대신 new Array()배열 리터럴을 []사용하십시오. JavaScript의 배열은 Java의 배열과 동일하게 작동하지 않으며 Java와 유사한 구문을 사용하면 혼동됩니다.

사용하지 마십시오 new Number, new String또는 new Boolean. 이러한 형식은 불필요한 객체 래퍼를 생성합니다. 대신 간단한 리터럴을 사용하십시오.

또한 주석을 확인하십시오- new Array(length)양식은 유용한 목적을 제공하지 않습니다 (적어도 오늘의 JavaScript 구현에서).


3
또한 Crockford는 new Array () 대신 []를 사용한다고 말합니다. 불행히도, 그는 연결된 기사에서 이유를 말하지 않습니다. 공간과 속도의 문제 일 뿐이라고 생각합니다. javascript.crockford.com/code.html
Nosredna 2016 년

4
Crockford는 "new"키워드를 사용하여 Javascript로 객체의 새 인스턴스를 만드는 것을 좋아하지 않습니다. 강의에서 모호함을 만들고 Javascript의 프로토 타입 스타일 상속과 잘 맞지 않는다고 자신의 생각이라고합니다. 그는 사용자가 만든 객체 생성자를 구체적으로 언급하고 있지만, 그러한 신념을 감안할 때 대체 구문이있을 때 내장 함수와 함께 사용하지 말 것을 권장하는 이유를 쉽게 알 수 있습니다.
Alan Storm

@ Alan Storm : 적어도 Number, String 및 Boolean의 경우 "이러한 형식은 불필요한 개체 래퍼를 생성합니다"라고 말하지만 배열에는 적용되지 않습니다.
BarelyFitz

10

더 잘 이해 []하고 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

위의 결과는 Windows 7의 Chrome 콘솔에서 얻은 것입니다.


4
하지만 왜 [] == [] 또는 [] === [] false입니까?
anu

5
"피연산자가 동일한 객체를 참조하는 경우에만 객체를 비교하는 표현식이 참입니다." (출처 : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )
srph

이 답변은 체리가 두 가지 구성이 동일하다는 것을 암시하는 예제를 선택합니다. 이 페이지의 다른 게시물은와 같 Array(3)거나 new Array(3)같지 않은 차이점을 지적합니다 [3].
ggorlen 2016 년

8

첫 번째는 기본 객체 생성자 호출입니다. 원하는 경우 매개 변수를 사용할 수 있습니다.

var array = new Array(5); //initialize with default length 5

두 번째 것은 비어 있지 않은 배열을 만들 수있는 기능입니다.

var array = [1, 2, 3]; // this array will contain numbers 1, 2, 3.

1
자세한 생성자를 사용하여 동일한 작업을 수행 할 수 있습니다. var array = new Array (1, 2, 3);
nickf

따라서 var array = [5]대괄호 를 사용할 수는 있지만 생성자를 사용하지 않고 var array = Array(5)5 개의 요소로 구성된 빈 배열을 만들 수 있습니다.
cdmckay

cdmckay-맞지 않습니다. var a = [5]는 단일 항목-숫자 5를 가진 배열입니다.
BarelyFitz

2
@BarelyFitz : 그것이 내가 말한 것입니다. Bogdans의 답변에서 그는 생성자 호출을 사용하여 배열을 초기화 할 수는 없지만 잘못되었습니다. 내 의견은 단지 생성자 호출을 사용하여 단일 요소의 배열을 초기화 할 수 없다는 것을 분명히하기위한 것입니다.
cdmckay

1
@ cdmckay : 죄송합니다, 귀하의 의견을 잘못 이해했습니다. 명확히하기 위해 : new Array (arg)-arg가 숫자이면 length = arg 인 빈 배열을 만듭니다. new Array (arg1, arg2)-새 배열을 만들고 배열 요소를 초기화합니다. 따라서 [5]와 같은 하나의 숫자 요소로 배열을 만들려면 new Array (5)를 사용하여 배열을 만들 수 없습니다. 그러나 실제로는 새로운 Array ()를 사용해서는 안되므로 요점입니다.
BarelyFitz

5

Fredrik의 좋은 예를 기반으로 한이 예부터 시작하여보다 구체적인 방법으로 설명 할 수 있습니다.

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

방금 배열에 다른 값을 추가하고 네 가지 경고를 표시했습니다. 첫 번째와 두 번째는 각 배열에 저장된 값을 제공하여 값을 확인하는 것입니다. 그들은 같은 것을 반환합니다! 이제 세 번째를 시도하십시오. 그것은 false를 반환합니다.

JS는 test1데이터 유형이 arrayVARIABLE로 취급하고 test2배열의 기능을 가진 OBJECT 로 취급 하며 여기에는 약간의 차이가 있습니다.

첫 번째 차이점은 test1을 호출 할 때 생각없이 변수를 호출하는 것입니다. 데이터 유형을 무시하고이 변수에 저장된 값만 반환합니다! 그러나 test2를 호출하면 Array () 함수를 호출 한 다음 "Pushed" 값을 "Value" 속성에 저장하고 test2를 경고 할 때 와 마찬가지로 배열 객체 의 "Value" 속성을 반환 합니다.

따라서 test1이 test2와 같은지 확인하면 절대로 true를 반환하지 않으며, 하나는 함수이고 다른 하나는 같은 값을 가지더라도 변수 (배열 유형)입니다.

이를 확인하려면 .value가 추가 된 네 번째 경고를 시도하십시오. true를 반환합니다. 이 경우 JS에게 "컨테이너의 유형을 무시하고 기능이나 변수에 관계없이 각 컨테이너에 저장된 값을 비교하여 본 내용을 알려주십시오!" 그것이 정확히 일어난 일입니다.

나는 그 아이디어를 명확하게 말하고 나의 나쁜 영어에 대해 유감스럽게 생각하기를 바랍니다.


19
이러한 완전하고 철저한 말도 안되는 투표를 한 것은 놀라운 일입니다. 배열 간의 비교는 객체의 정체성과 그것들이 다른 객체이기 때문에 어떻게 배열하든 거짓이됩니다. 배열에는 값 속성이 없습니다. []new Array()동일하다; .valueundefined두 경우 모두, 그 비교는 항상 거짓이 될 것입니다.
slikts

동의,이 대답은 의미가 없으며 아무 것도 보여주지 않습니다. 와 같은 것은 없습니다 array.value. 모두 typeof []typeof new Array()반환 object. 이것은 Array.isArray
gman

4

길이없이 배열을 초기화 할 때 차이가 없습니다. 그래서 var a = []& var b = new Array()동일합니다.

그러나 length와 같은 배열로 초기화하면 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

vs

var v = [];
a.push("hello world");
console.log(b.length); // print 1

3

첫 번째는 기본 객체 생성자 호출이며 주로 동적 값에 사용됩니다.

var array = new Array(length); //initialize with default length

두 번째 배열은 정적 값을 만들 때 사용됩니다

var array = [red, green, blue, yellow, white]; // this array will contain values.

3

큰 차이점은 없습니다. 기본적으로 동일한 작업을 수행하지만 다른 방식으로 수행하지만 W3C 에서이 진술을 읽으십시오.

var cars = ["Saab", "Volvo","BMW"];

var cars = new Array("Saab", "Volvo", "BMW");

위의 두 예는 정확히 동일합니다. new Array ()를 사용할 필요가 없습니다.
단순성, 가독성 및 실행 속도를 위해 첫 번째 방법 (배열 리터럴 방법)을 사용하십시오.

그러나 동시에 new Array나쁜 습관으로 간주되는 구문을 사용하여 새 배열을 작성하십시오 .

새로운 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)권장 길이가 아닌 길이를 전달할 수 있습니다 .


안녕하세요 Alireza, 이것들은 어딘가에서 복사하여 붙여 넣었습니까? 텍스트가 복사 된 페이지에 링크를 추가하십시오. 자세한 내용은 이 도움말 센터 페이지 를 참조하십시오. 감사합니다.
Pang

유용new Array(40).fill(123)
gman

2

사용의 차이점

var arr = new Array(size);

또는

arr = [];
arr.length = size;

이 질문에서 충분히 논의되었습니다.

속도 문제를 추가하고 싶습니다. 현재 가장 빠른 방법 google chrome은 두 번째 방법 입니다.

그러나 이러한 사항은 업데이트로 인해 많이 변경되는 경향이 있습니다. 또한 런타임은 브라우저마다 다릅니다.

예를 들어, 내가 언급 한 두 번째 옵션은에 2 백만 [ops / second]로 실행 chrome되지만, 시도하면 mozilla dev.2,300만의 놀랍도록 높은 비율을 얻게됩니다.

어쨌든, 사이트 사용하여 다른 브라우저 (및 컴퓨터)에서 가끔씩 체크 아웃하는 것이 좋습니다.


2

내가 diference 알고 u는 같은 슬라이스 (또는 배열의 다른 funcitons) 찾을 수 코드 1 .and CODE2 U에게 보여 배열 과 자신의 인스턴스를 :

코드 1 :

[].slice; // find slice here
var arr = new Array();
arr.slice // find slice here
Array.prototype.slice // find slice here

코드 2 :

[].__proto__ == Array.prototype; // true
var arr = new Array();
arr.__proto__ == Array.prototype; // true

결론:

u는 볼 수 []new Array()Array.And의 새 인스턴스를 만들 그들은 모두에서 프로토 타입 기능을 얻을Array.prototype

그것들은 단지 다른 배열의 인스턴스입니다. [] != []

:)


2

[]를 사용하여 이상한 동작이 발생했습니다.

필드가 어떤 값으로 초기화 된 모델 "클래스"가 있습니다. 예 :

require([
  "dojo/_base/declare",
  "dijit/_WidgetBase",
], function(declare, parser, ready, _WidgetBase){

   declare("MyWidget", [_WidgetBase], {
     field1: [],
     field2: "",
     function1: function(),
     function2: function()
   });    
});

필드가 초기화되면 []모든 Model 객체가 공유 한다는 것을 알았습니다 . 하나를 변경하면 다른 모든 사람들에게 영향을 미칩니다.

로 초기화하지 않습니다 new Array(). 객체 초기화와 동일 ( {}vs. new Object())

TBH 우리가 사용하고있는 프레임 워크에 문제가 있는지 확실하지 않습니다 ( Dojo )


2

눈을 만나는 것보다 더 많은 것이 있습니다. 대부분의 다른 답변도 정확 하지만 ..

new Array(n)

  • 엔진이 n요소를 위한 공간을 재 할당 할 수 있습니다
  • 어레이에 최적화 생성에
  • 생성 된 배열은 성능이 가장 낮은 배열 연산을 갖는 희소성 으로 표시됩니다. 이는 각 인덱스 액세스가 범위를 확인하고 값이 있는지 확인 하고 프로토 타입 체인을 따라야하기 때문입니다.
  • 배열이 희소로 표시되면 되돌릴 수있는 방법이 없으며 (적어도 V8에서는) 1ms 또는 2 시간 후에 내용 (패킹 된 배열)으로 채워도 상관없이 수명 기간 동안 항상 느려집니다.

[1, 2, 3] || []

  • 생성 된 배열은 압축 으로 표시됩니다 (사용 delete하거나 [1,,3]구문을 제외하고)
  • 어레이에 최적화 동작 ( for .., forEach, map등)
  • 어레이가 성장함에 따라 엔진은 공간을 재 할당해야합니다.

이것은 아마 오래된 브라우저 버전 / 브라우저의 경우에는 해당되지 않습니다.


-2

나는 두 건축 사이에서 한 가지 차이점을 발견했습니다.

내가 가지고 있다고 가정 해 봅시다.

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()합니다.


이 JSFiddle 은 배열 리터럴 []new Array()생성자 에서 출력이 예상 한 것으로 속성 당 배열 당 하나의 항목을 생성 함을 보여줍니다 . 위에 표시된 결과를 얻으려면 코드에 다른 일이 있어야합니다.
gfullam

버키, 그것은 어떤 브라우저에서도 일어나지 않습니다. 그 행동을하려면 다음과 같이해야합니다. var property1static=[]; function MyClass(){ this.property1=property1static; this.property2=new Array(); };
Dave Burton

-3

Array 생성자를 사용하면 원하는 길이의 새 배열이 만들어지고 각 인덱스가 정의되지 않은 채로 채워지고 변수 배열에 지정된 배열은 정보를 제공하는 인덱스를 만듭니다.


1
아니요, 배열이 채워지지 않았으며 내부에 색인 / 키가 없습니다. 예를 들어 .forEach는 작동하지 않습니다.
CFrei
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.