2017-01-09 8 views
1

を作成する配列の配列を作成し、これらの二つの異なる方法が異なる動作を生成することが、私を発見した:は、配列の配列異なる振る舞い

// Method 1 
for (var arr1 = []; arr.push([]) < len;) {} 

// Method 2 
var arr2 = new Array(len).fill([]) 

に作成したアレイは、コンソールで同じように見える、しかし、彼らは私の中で異なる動作をコード。これを引き起こす原因は何ですか?

+6

*配列の配列を作成しません - どのように? – Li357

答えて

1

アップデート:以下の回答は技術的に正確で、2つの方法の違いは、@Ori Droriの回答はほぼ確実にOPが探しているものです。

私はこれで刺すだろうが、より多くの文脈が役立つだろう。

通常、これらの2つのステートメントは同じように動作しますが、キーの違いがあります。newキーワードを使用すると、JavascriptインタープリタはArrayコンストラクタを呼び出します。

Arrayコンストラクタを上書きする場合、これはnewキーワードで定義されたarr2にのみ適用されます。配列リテラルで作成されたarr1は、依然としてJavascript配列です。一例として、

、のは、私は次のコードを書いたとしましょう:

function Array() { 
} 

方法1はまだ動作しますが、方法2は、フィルが関数ではありませんことを示す例外TypeErrorを返します。

興味深いことに、配列リテラル(メソッド1)を使用するとArrayコンストラクタが呼び出されるため、配列構造内でconsole.log("test");を実行した場合でも、どちらのメソッドを使用してもコンソールに出力されます。しかし、Arrayリテラル(メソッド1)を使用すると、Arrayコンストラクターが上書きされてもオブジェクト自体は標準のJavascript配列のままです。

3

違いは、第1の方法では各インデックスが異なる配列を指し、Array#fillではすべてのインデックスが同じ配列を指している点です。

注:第一の方法は、* "しかし、彼らは私のコードで異なる動作を"

var len = 3; 
 
var arr1 = []; 
 

 
// Method 1 
 
for (var arr1 = []; arr1.push([]) < len;) {} // new sub array is pushed into arr1 
 

 
// Method 2 
 
var arr2 = new Array(len).fill([]) // each place in the array is filled with a reference to the same array 
 

 
arr1[0].push(1); // push to the 1st element of arr1 
 
arr2[0].push(1); // push to the 1st element of arr2 
 

 
console.log('arr1: ', JSON.stringify(arr1)); // only the 1st sub array contains 1 
 
console.log('arr2: ', JSON.stringify(arr2)); // all sub arrays contain 1

+0

興味深い。私はいくつかのグーグルを行い、これを見つけた:https://chrisrng.svbtle.com/es6-array-prototype-fill – VKK

関連する問題