web-dev-qa-db-ja.com

JavaScriptの配列を宣言する際の "Array()"と "[]"の違いは何ですか?

このように配列を宣言することの本当の違いは何ですか:

var myArray = new Array();

そして

var myArray = [];
761
Amr Elgarhy

違いはありますが、その例に違いはありません。

より冗長な方法を使用すると、new Array()はパラメータに追加のオプションを1つ持ちます。コンストラクタに数値を渡すと、その長さの配列が得られます。

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

;
865
nickf

暗黙配列と配列コンストラクタを使って配列を作成することの違いは微妙ですが重要です。

を使って配列を作成するとき

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などのネイティブのArrayオブジェクト関数がすべて含まれていますが、その他には含まれていません。

これが起こることを期待するかもしれませんが、それは単に[]new Array()と同じではないという事実を示しています。

配列が欲しいということがわかっていれば、おそらく[]を使うのが最善です。私はまた、回避してArrayを再定義することもお勧めしません。

753
coderjoe

誰も言及していないという大きな違いがあります。

new Array(2)は、以前は[undefined, undefined]と同等だと思うかもしれません。

new Array(2).length           // 2
new Array(2)[0] === undefined // true
new Array(2)[1] === undefined // true

しかし、そうではありません!

map()を試してみましょう:

[undefined, undefined].map(e => 1)  // [1, 1]
new Array(2).map(e => 1)            // "(2) [undefined × 2]" in Chrome

見る?違います!しかし、それはなぜですか?

ES6仕様22.1.1.2によれば、Array(len)lengthlenに設定された新しい配列を作成するだけで、それ以上はありません。したがって、新しい配列の中に実要素はありません。

仕様22.1.3.15によれば、関数map()は最初に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 ]

この紛らわしいログを修正するように彼らに依頼するために私はすでに問題をChromeに提出しました: https://bugs.chromium.org/p/chromium/issues/detail?id=732021

更新:それはすでに修正されています。 Chromeは現在ログインしています

new Array(2)             // (2) [empty × 2]
70
Hux

奇妙なことに、new Array(size)はChromeの[]よりもほぼ2倍速く、FFとIE(配列を作成して満たすことで測定)でもほぼ同じです。あなたが配列のおおよそのサイズを知っている場合にだけ問題になります。指定した長さよりも多くのアイテムを追加すると、パフォーマンスの向上は失われます。

もっと正確に言うと、Array(はメモリを割り当てない高速の一定時間操作であり、[]は型と値を設定する線形時間操作です。

47
gblazex

詳細については、 次のページnew Array()を使用する必要がない理由についての説明があります。

JavaScriptでnew Object()を使う必要は決してありません。代わりにオブジェクトリテラル{}を使用してください。同様に、new Array()を使用せず、代わりに配列リテラル[]を使用してください。 JavaScriptの配列はJavaの配列と同じように機能しません。Java風の構文を使用すると混乱することがあります。

new Numbernew String、またはnew Booleanを使用しないでください。これらのフォームは不要なオブジェクトラッパーを生成します。代わりに単純なリテラルを使用してください。

コメントもチェックしてください - new Array(length)フォームは(少なくとも今日のJavaScriptの実装では)何の役に立つ目的にも役立ちません。

35
BarelyFitz

[]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上のGoogle Chromeコンソールからのものです。

9
Peter Lee

最初のものはデフォルトのオブジェクトコンストラクタ呼び出しです。あなたが望むならあなたはそれのパラメータを使うことができます。

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

2番目のものはあなたに空でない配列を作成する能力を与えます:

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

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

私は、配列に別の値を追加し、4つの警告を出しました。1番目と2番目は、各配列に格納されている値を確認して値を確認することです。彼らは同じを返します!今度は3番目のものを試してください、それはfalseを返します、それはなぜなら

JSはtest1データ型が配列 _として扱い、test2配列の機能を持つOBJECTとして扱います。そして、ここにはわずかな違いがほとんどありません。

最初の違いは、test1を呼び出すと、考えずに変数を呼び出すときに、データ型を無視してこの変数に格納されている値を返すことです。しかし、test2を呼び出すと、 Array() 関数が呼び出され、 "Value" プロパティに "Pressed" の値が格納されます。 test2に警告すると起こります、それは配列オブジェクトの "Value" プロパティを返します。

そのため、test1がtest2と等しいかどうかを確かめるとき、もちろんそれらは決して真を返さないでしょう、それらは同じ値を持っていても、(配列の型を持つ)関数と変数です。

これを確実にするために、4番目のアラートに、.valueを追加して試してください。それはtrueを返します。この場合、JSに "コンテナの型を無視します。それが関数か変数かに関わらず、各コンテナに格納されている値を比較して、あなたが見たことを教えてください!"それがまさに起こることです。

その背後にある考えをはっきりと述べ、私の悪い英語を残念に思っていると私は願っています。

5
Kholio

私が知っているように、差uはcode1。and code2 show uArrayと彼のインスタンス

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

結論:

uは[]new Array()を見ることができるので、Arrayの新しいインスタンスを作成します。そして、それらはすべてArray.prototypeからプロトタイプ関数を取得します。

それらは単にArrayの異なるインスタンスです。したがって、これは[] != []の理由を説明します

:)

2
sammy

大きな違いはありません。基本的には同じことを行いますが、方法は異なりますが、W3Cでこのステートメントを確認してください。

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

そして

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

上記の2つの例はまったく同じです。 new Array()を使用する必要はありません。
単純さ、読みやすさ、そして実行速度のために、最初のもの(配列リテラルメソッド)を使用してください。

しかし同時に、new Array構文を使用して新しい配列を作成することは悪い習慣と考えられています。

new Array()を避けます

JavaScriptの組み込み配列コンストラクタnew Array()を使用する必要はありません。
代わりに[]を使用してください。
これら2つの異なるステートメントは、どちらもpointsという名前の新しい空の配列を作成します。

var points = new Array();         // Bad
var points = [];                  // Good 

これら2つの異なるステートメントは両方とも6つの数字を含む新しい配列を作成します。

var points = new Array(40, 100, 1, 5, 25, 10); // Bad    
var points = [40, 100, 1, 5, 25, 10];          // Good

new キーワードはコードを複雑にするだけです。また、予期しない結果が生じることもあります。

var points = new Array(40, 100);  // Creates an array with two elements (40 and 100)

要素の1つを削除したらどうなりますか?

var points = new Array(40);       // Creates an array with 40 undefined elements !!!!!

基本的にはベストプラクティスとは考えられていませんが、ちょっとした違いが1つあります。このようにnew Array(length)に長さを渡すこともできますが、これもお勧めできません。

2
Alireza

最初のものはデフォルトのオブジェクトコンストラクタcallです。動的な値によく使われます。

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

2番目の配列は静的な値を作成するときに使われます

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

使用の違い

var arr = new Array(size);

または

arr = [];
arr.length = size;

この質問で十分に議論されたように。

スピードの問題を付け加えたいのですが 現在 最速の方法は、google chromeは2番目です。

しかし、注意を払ってください、これらのことは更新で大きく変わる傾向があります。また、ランタイムはブラウザによって異なります。

例えば ​​- 私が言及した2番目のオプションはchrome上で200万[ops/second]で実行されますが、もしあなたがmozilla dev.上でそれを試したければあなたは2300万の驚くほど高いレートを得るでしょう。

とにかく、site を使用して、時々、異なるブラウザ(およびマシン)でチェックアウトすることをお勧めします

1
Meir Elad

私は[]を使って奇妙な振る舞いをしました。

フィールドに値が初期化されたモデル「クラス」があります。例えば。:

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

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

フィールドが[]で初期化されると、それはすべてのModelオブジェクトによって共有されることに気付きました。変更すると他のすべてに影響します。

これはnew Array()でそれらを初期化することでは起こりません。オブジェクトの初期化と同じです({}とnew Object())。

TBH私たちが使っていたフレームワークに問題があるのか​​どうか私にはわかりません( Dojo

1
algiogia

配列を長さなしで初期化しても違いはありません。だからvar a = []var b = new Array()は同じです。

しかし、var b = new Array(1);のように長さを指定してarrayを初期化すると、配列オブジェクトの長さは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
1
Aniruddha