3

JavaScriptはどういうわけかコードを最適化しようとしているようです。したがって、ループ内largeArrで1次元配列(smallArr)の値を変更して多次元配列()を埋めたい場合は、次のコードを使用します。

largeArr = []
smallArr = []

for (i=0; i<2; i++)
{
    smallArr[0]=i
    smallArr[1]=2*i

    largeArr[i]=smallArr
}

予期しない結果が得られます:(であるlargeArr=[[1,2],[1,2]]必要があります[[0,0],[1,2]])。したがって、JavascriptsmallArrは最初に値を計算し、次に値を入力しますlargeArr。正しい結果を得るにはsmallArr、ループで宣言する必要があります。

largeArr = []

for (i=0; i<2; i++)
{
    smallArr = []
    smallArr[0]=i
    smallArr[1]=2*i

    largeArr[i]=smallArr
}

その後、期待どおりに機能します(largeArr=[[0,0],[1,2]])。

なぜこのように動作するのですか?

4

4 に答える 4

4

ポインタだからです。Javascript は、Java と C をこの (そしてこれだけの) 方法で引き継いでいます。宿題をするとき

largeArr[i] = smallArr

ポインタを割り当てています。ポインターの内訳:

C (程度は低いが Java と Javascript) では、基本的な配列型はありません。代わりに、配列はメモリ内のスペースを指し、そのスペースを必要な情報で埋めることができます (または、むしろ、あなたが宣言しました)。ポインターがメモリ内に存在する方法は? 4 (またはシステムによっては 8、または 2) バイトのメモリ アドレス。コンパイラ/パーサーに適切な情報を取得する場所を指示します。したがって、そこでその割り当てを行うときは、「ねえ、largeArr[i] を smallArr のメモリ アドレスに等しく設定してください」と伝えていることになります。したがって、smallArr に変更を加えると、実際には同じ配列であるため、配列を逆参照するたびに反映されます。しかし、あなたがするとき:

smallArr = [] 

ループ内では、「新しい配列を作成し、smallArr をその配列のアドレスに等しく設定する」と言っています。そうすれば、配列は分離したままになります。

于 2012-12-03T22:00:18.490 に答える
0

の行で、プロパティを への参照にlargeArr[i]=smallArr設定します。あなたはそれをコピーしません。最後に、 will のすべてのプロパティは、毎回値を上書きした同じものを指します。ismallArrlargeArrsmallArr

各ループ ターンを初期化することによりsmallArr、新しいオブジェクトを作成します。そのため、の各プロパティはlargeArr異なる配列を指します。ところで、これは割り当てであり、宣言ではありません。varステートメントを使用して、変数をローカル (関数に対して) として宣言します (また、宣言する必要があります) 。

于 2012-12-03T22:02:22.627 に答える
0

繰り返しの最後に

smallArr[0]=i
smallArr[1]=2*i  

(ここでi=1) 上記のコードは次のように変換されます。

smallArr[0]=1
smallArr[1]=2

そして、あなたの大きな配列はこれに他なりません:

[smallArr, smallArr]

これは予期しない結果につながります:

[[1, 2], [1, 2]]

JavaScript では、オブジェクトは参照によってコピーされます (一種の C スタイル ポインター)。
目的の結果を得るには、配列を値でコピーするか、各ループで異なる配列を割り当てる必要があります。

var largeArr = [];

for (i=0; i<2; i++)
   largeArr[i] = [[i, 2*i]];
于 2012-12-03T22:03:05.080 に答える
0

上記のように配列参照を割り当てる場合、その配列のを割り当てるのではなく、配列へ参照のみを割り当てます。

ポインタと考えてください。largeArr[0] と largeArr[1] は smallArr を指しており、ループの反復は単に smallArr の内容を変更しています。largeArr が「指摘」されていることは変わりません。

于 2012-12-03T22:05:48.713 に答える